diff options
54 files changed, 1186 insertions, 201 deletions
diff --git a/bootstrap/bin/start.script b/bootstrap/bin/start.script index 590af335ce..08ed9939f7 100644 --- a/bootstrap/bin/start.script +++ b/bootstrap/bin/start.script @@ -1,4 +1,4 @@ -%% script generated at {2010,5,10} {6,51,10} +%% script generated at {2010,5,11} {9,2,55} {script, {"OTP APN 181 01","R14A"}, [{preLoaded, diff --git a/bootstrap/bin/start_clean.script b/bootstrap/bin/start_clean.script index 590af335ce..08ed9939f7 100644 --- a/bootstrap/bin/start_clean.script +++ b/bootstrap/bin/start_clean.script @@ -1,4 +1,4 @@ -%% script generated at {2010,5,10} {6,51,10} +%% script generated at {2010,5,11} {9,2,55} {script, {"OTP APN 181 01","R14A"}, [{preLoaded, diff --git a/bootstrap/lib/compiler/ebin/beam_disasm.beam b/bootstrap/lib/compiler/ebin/beam_disasm.beam Binary files differindex c1fe43b398..b58b44c68c 100644 --- a/bootstrap/lib/compiler/ebin/beam_disasm.beam +++ b/bootstrap/lib/compiler/ebin/beam_disasm.beam diff --git a/bootstrap/lib/compiler/ebin/beam_opcodes.beam b/bootstrap/lib/compiler/ebin/beam_opcodes.beam Binary files differindex 34327c700e..8c5378e05e 100644 --- a/bootstrap/lib/compiler/ebin/beam_opcodes.beam +++ b/bootstrap/lib/compiler/ebin/beam_opcodes.beam diff --git a/bootstrap/lib/compiler/ebin/beam_receive.beam b/bootstrap/lib/compiler/ebin/beam_receive.beam Binary files differnew file mode 100644 index 0000000000..ef7afd8113 --- /dev/null +++ b/bootstrap/lib/compiler/ebin/beam_receive.beam diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam Binary files differindex 2edf5f226e..e04c9efa69 100644 --- a/bootstrap/lib/compiler/ebin/beam_validator.beam +++ b/bootstrap/lib/compiler/ebin/beam_validator.beam diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam Binary files differindex f989cdc1df..3d44822af6 100644 --- a/bootstrap/lib/compiler/ebin/compile.beam +++ b/bootstrap/lib/compiler/ebin/compile.beam diff --git a/bootstrap/lib/compiler/ebin/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app index 497d1873d8..ed0dd7c30e 100644 --- a/bootstrap/lib/compiler/ebin/compiler.app +++ b/bootstrap/lib/compiler/ebin/compiler.app @@ -33,6 +33,7 @@ beam_listing, beam_opcodes, beam_peep, + beam_receive, beam_trim, beam_type, beam_utils, diff --git a/bootstrap/lib/compiler/egen/beam_opcodes.erl b/bootstrap/lib/compiler/egen/beam_opcodes.erl index 83cdaa4d48..05587800b4 100644 --- a/bootstrap/lib/compiler/egen/beam_opcodes.erl +++ b/bootstrap/lib/compiler/egen/beam_opcodes.erl @@ -8,7 +8,7 @@ -spec format_number() -> 0. format_number() -> 0. --spec opcode(atom(), 0..8) -> 1..149. +-spec opcode(atom(), 0..8) -> 1..151. opcode(label, 1) -> 1; opcode(func_info, 3) -> 2; opcode(int_code_end, 0) -> 3; @@ -158,9 +158,11 @@ opcode(bs_utf16_size, 3) -> 146; opcode(bs_put_utf16, 3) -> 147; opcode(bs_put_utf32, 3) -> 148; opcode(on_load, 0) -> 149; +opcode(recv_mark, 1) -> 150; +opcode(recv_set, 1) -> 151; opcode(Name, Arity) -> erlang:error(badarg, [Name,Arity]). --spec opname(1..149) -> {atom(),0..8}. +-spec opname(1..151) -> {atom(),0..8}. opname(1) -> {label,1}; opname(2) -> {func_info,3}; opname(3) -> {int_code_end,0}; @@ -310,4 +312,6 @@ opname(146) -> {bs_utf16_size,3}; opname(147) -> {bs_put_utf16,3}; opname(148) -> {bs_put_utf32,3}; opname(149) -> {on_load,0}; +opname(150) -> {recv_mark,1}; +opname(151) -> {recv_set,1}; opname(Number) -> erlang:error(badarg, [Number]). diff --git a/bootstrap/lib/compiler/egen/core_parse.erl b/bootstrap/lib/compiler/egen/core_parse.erl index 05624beb14..093ab4d1a3 100644 --- a/bootstrap/lib/compiler/egen/core_parse.erl +++ b/bootstrap/lib/compiler/egen/core_parse.erl @@ -13,7 +13,7 @@ tok_val(T) -> element(3, T). tok_line(T) -> element(2, T). --file("/usr/local/otp/releases/sles10_32_R13B04_patched/lib/parsetools-2.0.2/include/yeccpre.hrl", 0). +-file("/usr/local/lib/erlang/lib/parsetools-2.0.2/include/yeccpre.hrl", 0). %% %% %CopyrightBegin% %% @@ -194,7 +194,7 @@ yecctoken2string(Other) -> --file("/clearcase/otp/erts/bootstrap/lib/compiler/egen/core_parse.erl", 197). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/compiler/egen/core_parse.erl", 197). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); diff --git a/bootstrap/lib/kernel/ebin/code_server.beam b/bootstrap/lib/kernel/ebin/code_server.beam Binary files differindex 894e6ca2ea..5bf9b13367 100644 --- a/bootstrap/lib/kernel/ebin/code_server.beam +++ b/bootstrap/lib/kernel/ebin/code_server.beam diff --git a/bootstrap/lib/kernel/ebin/global.beam b/bootstrap/lib/kernel/ebin/global.beam Binary files differindex b16334d8a2..4dc43450f0 100644 --- a/bootstrap/lib/kernel/ebin/global.beam +++ b/bootstrap/lib/kernel/ebin/global.beam diff --git a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam Binary files differindex b46fd6ba87..e712d25405 100644 --- a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam +++ b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam diff --git a/bootstrap/lib/kernel/ebin/pg2.beam b/bootstrap/lib/kernel/ebin/pg2.beam Binary files differindex 38870b0f43..51912f2263 100644 --- a/bootstrap/lib/kernel/ebin/pg2.beam +++ b/bootstrap/lib/kernel/ebin/pg2.beam diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam Binary files differindex e9a9d4a8f0..71e0d21db1 100644 --- a/bootstrap/lib/stdlib/ebin/epp.beam +++ b/bootstrap/lib/stdlib/ebin/epp.beam diff --git a/bootstrap/lib/stdlib/ebin/gen.beam b/bootstrap/lib/stdlib/ebin/gen.beam Binary files differindex bf09b84de6..4b047eb838 100644 --- a/bootstrap/lib/stdlib/ebin/gen.beam +++ b/bootstrap/lib/stdlib/ebin/gen.beam diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam Binary files differindex f3373cf593..8d76d138f1 100644 --- a/bootstrap/lib/stdlib/ebin/gen_server.beam +++ b/bootstrap/lib/stdlib/ebin/gen_server.beam diff --git a/bootstrap/lib/stdlib/egen/erl_parse.erl b/bootstrap/lib/stdlib/egen/erl_parse.erl index 8c215d81c0..2f985589c9 100644 --- a/bootstrap/lib/stdlib/egen/erl_parse.erl +++ b/bootstrap/lib/stdlib/egen/erl_parse.erl @@ -547,7 +547,7 @@ get_attribute(L, Name) -> get_attributes(L) -> erl_scan:attributes_info(L). --file("/usr/local/otp/releases/sles10_32_R13B04_patched/lib/parsetools-2.0.2/include/yeccpre.hrl", 0). +-file("/usr/local/lib/erlang/lib/parsetools-2.0.2/include/yeccpre.hrl", 0). %% %% %CopyrightBegin% %% @@ -728,7 +728,7 @@ yecctoken2string(Other) -> --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 731). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 731). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); @@ -7636,7 +7636,7 @@ yeccpars2_39_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7639). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7639). -compile({inline,yeccpars2_46_/1}). -file("erl_parse.yrl", 423). yeccpars2_46_(__Stack0) -> @@ -7645,7 +7645,7 @@ yeccpars2_46_(__Stack0) -> { [ ] , ? line ( __1 ) } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7648). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7648). -compile({inline,yeccpars2_70_/1}). -file("erl_parse.yrl", 314). yeccpars2_70_(__Stack0) -> @@ -7654,7 +7654,7 @@ yeccpars2_70_(__Stack0) -> { tuple , ? line ( __1 ) , [ ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7657). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7657). -compile({inline,yeccpars2_71_/1}). -file("erl_parse.yrl", 315). yeccpars2_71_(__Stack0) -> @@ -7663,7 +7663,7 @@ yeccpars2_71_(__Stack0) -> { tuple , ? line ( __1 ) , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7666). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7666). -compile({inline,yeccpars2_73_/1}). -file("erl_parse.yrl", 397). yeccpars2_73_(__Stack0) -> @@ -7695,7 +7695,7 @@ yeccpars2_81_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7698). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7698). -compile({inline,yeccpars2_82_/1}). -file("erl_parse.yrl", 395). yeccpars2_82_(__Stack0) -> @@ -7728,7 +7728,7 @@ yeccpars2_88_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7731). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7731). -compile({inline,yeccpars2_89_/1}). -file("erl_parse.yrl", 370). yeccpars2_89_(__Stack0) -> @@ -7767,7 +7767,7 @@ yeccpars2_98_(__Stack0) -> [ ] end | __Stack0]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7770). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7770). -compile({inline,yeccpars2_100_/1}). -file("erl_parse.yrl", 416). yeccpars2_100_(__Stack0) -> @@ -7784,7 +7784,7 @@ yeccpars2_102_(__Stack0) -> [ ] end | __Stack0]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7787). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7787). -compile({inline,yeccpars2_104_/1}). -file("erl_parse.yrl", 413). yeccpars2_104_(__Stack0) -> @@ -7794,7 +7794,7 @@ yeccpars2_104_(__Stack0) -> { clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7797). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7797). -compile({inline,yeccpars2_106_/1}). -file("erl_parse.yrl", 410). yeccpars2_106_(__Stack0) -> @@ -7836,7 +7836,7 @@ yeccpars2_114_(__Stack0) -> { [ ] , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7839). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7839). -compile({inline,yeccpars2_115_/1}). -file("erl_parse.yrl", 441). yeccpars2_115_(__Stack0) -> @@ -7845,7 +7845,7 @@ yeccpars2_115_(__Stack0) -> { string , ? line ( __1 ) , element ( 3 , __1 ) ++ element ( 3 , __2 ) } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7848). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7848). -compile({inline,yeccpars2_120_/1}). -file("erl_parse.yrl", 375). yeccpars2_120_(__Stack0) -> @@ -7854,7 +7854,7 @@ yeccpars2_120_(__Stack0) -> { 'receive' , ? line ( __1 ) , [ ] , __3 , __4 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7857). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7857). -compile({inline,yeccpars2_122_/1}). -file("erl_parse.yrl", 373). yeccpars2_122_(__Stack0) -> @@ -7863,7 +7863,7 @@ yeccpars2_122_(__Stack0) -> { 'receive' , ? line ( __1 ) , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7866). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7866). -compile({inline,yeccpars2_125_/1}). -file("erl_parse.yrl", 377). yeccpars2_125_(__Stack0) -> @@ -7880,7 +7880,7 @@ yeccpars2_131_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7883). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7883). -compile({inline,yeccpars2_135_/1}). -file("erl_parse.yrl", 312). yeccpars2_135_(__Stack0) -> @@ -7889,7 +7889,7 @@ yeccpars2_135_(__Stack0) -> { b_generate , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7892). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7892). -compile({inline,yeccpars2_137_/1}). -file("erl_parse.yrl", 311). yeccpars2_137_(__Stack0) -> @@ -7906,7 +7906,7 @@ yeccpars2_139_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7909). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7909). -compile({inline,yeccpars2_140_/1}). -file("erl_parse.yrl", 304). yeccpars2_140_(__Stack0) -> @@ -7915,7 +7915,7 @@ yeccpars2_140_(__Stack0) -> { lc , ? line ( __1 ) , __2 , __4 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7918). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7918). -compile({inline,yeccpars2_141_/1}). -file("erl_parse.yrl", 420). yeccpars2_141_(__Stack0) -> @@ -7932,7 +7932,7 @@ yeccpars2_143_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7935). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7935). -compile({inline,yeccpars2_145_/1}). -file("erl_parse.yrl", 360). yeccpars2_145_(__Stack0) -> @@ -7949,7 +7949,7 @@ yeccpars2_147_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7952). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7952). -compile({inline,yeccpars2_148_/1}). -file("erl_parse.yrl", 354). yeccpars2_148_(__Stack0) -> @@ -7973,7 +7973,7 @@ yeccpars2_151_(__Stack0) -> [ ] end | __Stack0]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7976). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7976). -compile({inline,yeccpars2_157_/1}). -file("erl_parse.yrl", 383). yeccpars2_157_(__Stack0) -> @@ -7982,7 +7982,7 @@ yeccpars2_157_(__Stack0) -> { 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) , element ( 3 , __6 ) } } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7985). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7985). -compile({inline,yeccpars2_158_/1}). -file("erl_parse.yrl", 381). yeccpars2_158_(__Stack0) -> @@ -8008,7 +8008,7 @@ yeccpars2_162_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8011). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8011). -compile({inline,yeccpars2_163_/1}). -file("erl_parse.yrl", 385). yeccpars2_163_(__Stack0) -> @@ -8017,7 +8017,7 @@ yeccpars2_163_(__Stack0) -> build_fun ( ? line ( __1 ) , __2 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8020). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8020). -compile({inline,yeccpars2_164_/1}). -file("erl_parse.yrl", 203). yeccpars2_164_(__Stack0) -> @@ -8026,7 +8026,7 @@ yeccpars2_164_(__Stack0) -> { 'catch' , ? line ( __1 ) , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8029). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8029). -compile({inline,yeccpars2_168_/1}). -file("erl_parse.yrl", 364). yeccpars2_168_(__Stack0) -> @@ -8035,7 +8035,7 @@ yeccpars2_168_(__Stack0) -> { 'case' , ? line ( __1 ) , __2 , __4 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8038). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8038). -compile({inline,yeccpars2_170_/1}). -file("erl_parse.yrl", 259). yeccpars2_170_(__Stack0) -> @@ -8044,7 +8044,7 @@ yeccpars2_170_(__Stack0) -> { block , ? line ( __1 ) , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8047). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8047). -compile({inline,yeccpars2_172_/1}). -file("erl_parse.yrl", 268). yeccpars2_172_(__Stack0) -> @@ -8053,7 +8053,7 @@ yeccpars2_172_(__Stack0) -> { nil , ? line ( __1 ) } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8056). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8056). -compile({inline,yeccpars2_173_/1}). -file("erl_parse.yrl", 269). yeccpars2_173_(__Stack0) -> @@ -8062,7 +8062,7 @@ yeccpars2_173_(__Stack0) -> { cons , ? line ( __1 ) , __2 , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8065). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8065). -compile({inline,yeccpars2_175_/1}). -file("erl_parse.yrl", 271). yeccpars2_175_(__Stack0) -> @@ -8079,7 +8079,7 @@ yeccpars2_178_(__Stack0) -> __2 end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8082). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8082). -compile({inline,yeccpars2_180_/1}). -file("erl_parse.yrl", 273). yeccpars2_180_(__Stack0) -> @@ -8103,7 +8103,7 @@ yeccpars2_186_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8106). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8106). -compile({inline,yeccpars2_187_/1}). -file("erl_parse.yrl", 276). yeccpars2_187_(__Stack0) -> @@ -8120,7 +8120,7 @@ yeccpars2_189_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8123). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8123). -compile({inline,yeccpars2_190_/1}). -file("erl_parse.yrl", 277). yeccpars2_190_(__Stack0) -> @@ -8129,7 +8129,7 @@ yeccpars2_190_(__Stack0) -> { bin , ? line ( __1 ) , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8132). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8132). -compile({inline,yeccpars2_193_/1}). -file("erl_parse.yrl", 306). yeccpars2_193_(__Stack0) -> @@ -8153,7 +8153,7 @@ yeccpars2_197_(__Stack0) -> __2 end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8156). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8156). -compile({inline,yeccpars2_198_/1}). -file("erl_parse.yrl", 283). yeccpars2_198_(__Stack0) -> @@ -8202,7 +8202,7 @@ yeccpars2_206_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8205). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8205). -compile({inline,yeccpars2_207_/1}). -file("erl_parse.yrl", 285). yeccpars2_207_(__Stack0) -> @@ -8211,7 +8211,7 @@ yeccpars2_207_(__Stack0) -> ? mkop1 ( __1 , __2 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8214). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8214). -compile({inline,yeccpars2_208_/1}). -file("erl_parse.yrl", 245). yeccpars2_208_(__Stack0) -> @@ -8228,7 +8228,7 @@ yeccpars2_210_(__Stack0) -> __2 end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8231). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8231). -compile({inline,yeccpars2_212_/1}). -file("erl_parse.yrl", 329). yeccpars2_212_(__Stack0) -> @@ -8253,7 +8253,7 @@ yeccpars2_219_(__Stack0) -> [ ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8256). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8256). -compile({inline,yeccpars2_221_/1}). -file("erl_parse.yrl", 345). yeccpars2_221_(__Stack0) -> @@ -8262,7 +8262,7 @@ yeccpars2_221_(__Stack0) -> { record_field , ? line ( __1 ) , __1 , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8265). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8265). -compile({inline,yeccpars2_223_/1}). -file("erl_parse.yrl", 346). yeccpars2_223_(__Stack0) -> @@ -8287,7 +8287,7 @@ yeccpars2_226_(__Stack0) -> __2 end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8290). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8290). -compile({inline,yeccpars2_227_/1}). -file("erl_parse.yrl", 327). yeccpars2_227_(__Stack0) -> @@ -8304,7 +8304,7 @@ yeccpars2_229_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8307). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8307). -compile({inline,yeccpars2_232_/1}). -file("erl_parse.yrl", 206). yeccpars2_232_(__Stack0) -> @@ -8313,7 +8313,7 @@ yeccpars2_232_(__Stack0) -> { match , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8316). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8316). -compile({inline,yeccpars2_233_/1}). -file("erl_parse.yrl", 207). yeccpars2_233_(__Stack0) -> @@ -8322,7 +8322,7 @@ yeccpars2_233_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8325). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8325). -compile({inline,yeccpars2_235_/1}). -file("erl_parse.yrl", 210). yeccpars2_235_(__Stack0) -> @@ -8331,7 +8331,7 @@ yeccpars2_235_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8334). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8334). -compile({inline,yeccpars2_237_/1}). -file("erl_parse.yrl", 213). yeccpars2_237_(__Stack0) -> @@ -8340,7 +8340,7 @@ yeccpars2_237_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8343). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8343). -compile({inline,yeccpars2_247_/1}). -file("erl_parse.yrl", 217). yeccpars2_247_(__Stack0) -> @@ -8349,7 +8349,7 @@ yeccpars2_247_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8352). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8352). -compile({inline,yeccpars2_260_/1}). -file("erl_parse.yrl", 225). yeccpars2_260_(__Stack0) -> @@ -8358,7 +8358,7 @@ yeccpars2_260_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8361). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8361). -compile({inline,yeccpars2_268_/1}). -file("erl_parse.yrl", 229). yeccpars2_268_(__Stack0) -> @@ -8367,7 +8367,7 @@ yeccpars2_268_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8370). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8370). -compile({inline,yeccpars2_269_/1}). -file("erl_parse.yrl", 221). yeccpars2_269_(__Stack0) -> @@ -8376,7 +8376,7 @@ yeccpars2_269_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8379). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8379). -compile({inline,yeccpars2_270_/1}). -file("erl_parse.yrl", 351). yeccpars2_270_(__Stack0) -> @@ -8385,7 +8385,7 @@ yeccpars2_270_(__Stack0) -> { call , ? line ( __1 ) , __1 , element ( 1 , __2 ) } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8388). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8388). -compile({inline,yeccpars2_273_/1}). -file("erl_parse.yrl", 241). yeccpars2_273_(__Stack0) -> @@ -8394,7 +8394,7 @@ yeccpars2_273_(__Stack0) -> { remote , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8397). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8397). -compile({inline,yeccpars2_274_/1}). -file("erl_parse.yrl", 247). yeccpars2_274_(__Stack0) -> @@ -8403,7 +8403,7 @@ yeccpars2_274_(__Stack0) -> { record_field , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8406). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8406). -compile({inline,yeccpars2_277_/1}). -file("erl_parse.yrl", 333). yeccpars2_277_(__Stack0) -> @@ -8412,7 +8412,7 @@ yeccpars2_277_(__Stack0) -> { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8415). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8415). -compile({inline,yeccpars2_279_/1}). -file("erl_parse.yrl", 331). yeccpars2_279_(__Stack0) -> @@ -8421,7 +8421,7 @@ yeccpars2_279_(__Stack0) -> { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8424). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8424). -compile({inline,yeccpars2_280_/1}). -file("erl_parse.yrl", 424). yeccpars2_280_(__Stack0) -> @@ -8430,7 +8430,7 @@ yeccpars2_280_(__Stack0) -> { __2 , ? line ( __1 ) } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8433). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8433). -compile({inline,yeccpars2_281_/1}). -file("erl_parse.yrl", 233). yeccpars2_281_(__Stack0) -> @@ -8439,7 +8439,7 @@ yeccpars2_281_(__Stack0) -> ? mkop1 ( __1 , __2 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8442). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8442). -compile({inline,yeccpars2_284_/1}). -file("erl_parse.yrl", 337). yeccpars2_284_(__Stack0) -> @@ -8448,7 +8448,7 @@ yeccpars2_284_(__Stack0) -> { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8451). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8451). -compile({inline,yeccpars2_286_/1}). -file("erl_parse.yrl", 335). yeccpars2_286_(__Stack0) -> @@ -8457,7 +8457,7 @@ yeccpars2_286_(__Stack0) -> { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8460). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8460). -compile({inline,yeccpars2_288_/1}). -file("erl_parse.yrl", 482). yeccpars2_288_(__Stack0) -> @@ -8466,7 +8466,7 @@ yeccpars2_288_(__Stack0) -> { clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8469). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8469). -compile({inline,yeccpars2_289_/1}). -file("erl_parse.yrl", 192). yeccpars2_289_(__Stack0) -> @@ -8531,7 +8531,7 @@ yeccpars2_314_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8534). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8534). -compile({inline,yeccpars2_329_/1}). -file("erl_parse.yrl", 135). yeccpars2_329_(__Stack0) -> @@ -8540,7 +8540,7 @@ yeccpars2_329_(__Stack0) -> { type , ? line ( __1 ) , tuple , [ ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8543). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8543). -compile({inline,yeccpars2_330_/1}). -file("erl_parse.yrl", 136). yeccpars2_330_(__Stack0) -> @@ -8549,7 +8549,7 @@ yeccpars2_330_(__Stack0) -> { type , ? line ( __1 ) , tuple , __2 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8552). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8552). -compile({inline,yeccpars2_332_/1}). -file("erl_parse.yrl", 115). yeccpars2_332_(__Stack0) -> @@ -8558,7 +8558,7 @@ yeccpars2_332_(__Stack0) -> { ann_type , ? line ( __1 ) , [ __1 , __3 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8561). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8561). -compile({inline,yeccpars2_338_/1}). -file("erl_parse.yrl", 144). yeccpars2_338_(__Stack0) -> @@ -8567,7 +8567,7 @@ yeccpars2_338_(__Stack0) -> { type , ? line ( __1 ) , 'fun' , [ ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8570). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8570). -compile({inline,yeccpars2_344_/1}). -file("erl_parse.yrl", 152). yeccpars2_344_(__Stack0) -> @@ -8585,7 +8585,7 @@ yeccpars2_345_(__Stack0) -> __3 end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8588). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8588). -compile({inline,yeccpars2_351_/1}). -file("erl_parse.yrl", 127). yeccpars2_351_(__Stack0) -> @@ -8595,7 +8595,7 @@ yeccpars2_351_(__Stack0) -> [ __1 , __3 , [ ] ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8598). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8598). -compile({inline,yeccpars2_352_/1}). -file("erl_parse.yrl", 129). yeccpars2_352_(__Stack0) -> @@ -8613,7 +8613,7 @@ yeccpars2_354_(__Stack0) -> build_gen_type ( __1 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8616). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8616). -compile({inline,yeccpars2_355_/1}). -file("erl_parse.yrl", 125). yeccpars2_355_(__Stack0) -> @@ -8623,7 +8623,7 @@ yeccpars2_355_(__Stack0) -> normalise ( __1 ) , __3 } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8626). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8626). -compile({inline,yeccpars2_357_/1}). -file("erl_parse.yrl", 131). yeccpars2_357_(__Stack0) -> @@ -8632,7 +8632,7 @@ yeccpars2_357_(__Stack0) -> { type , ? line ( __1 ) , nil , [ ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8635). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8635). -compile({inline,yeccpars2_359_/1}). -file("erl_parse.yrl", 132). yeccpars2_359_(__Stack0) -> @@ -8641,7 +8641,7 @@ yeccpars2_359_(__Stack0) -> { type , ? line ( __1 ) , list , [ __2 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8644). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8644). -compile({inline,yeccpars2_363_/1}). -file("erl_parse.yrl", 133). yeccpars2_363_(__Stack0) -> @@ -8651,7 +8651,7 @@ yeccpars2_363_(__Stack0) -> nonempty_list , [ __2 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8654). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8654). -compile({inline,yeccpars2_366_/1}). -file("erl_parse.yrl", 168). yeccpars2_366_(__Stack0) -> @@ -8678,7 +8678,7 @@ yeccpars2_372_(__Stack0) -> build_bin_type ( [ __1 , __3 ] , __5 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8681). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8681). -compile({inline,yeccpars2_374_/1}). -file("erl_parse.yrl", 171). yeccpars2_374_(__Stack0) -> @@ -8688,7 +8688,7 @@ yeccpars2_374_(__Stack0) -> [ __2 , abstract ( 0 , ? line ( __1 ) ) ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8691). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8691). -compile({inline,yeccpars2_378_/1}). -file("erl_parse.yrl", 176). yeccpars2_378_(__Stack0) -> @@ -8697,7 +8697,7 @@ yeccpars2_378_(__Stack0) -> { type , ? line ( __1 ) , binary , [ __2 , __4 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8700). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8700). -compile({inline,yeccpars2_379_/1}). -file("erl_parse.yrl", 173). yeccpars2_379_(__Stack0) -> @@ -8707,7 +8707,7 @@ yeccpars2_379_(__Stack0) -> [ abstract ( 0 , ? line ( __1 ) ) , __2 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8710). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8710). -compile({inline,yeccpars2_380_/1}). -file("erl_parse.yrl", 148). yeccpars2_380_(__Stack0) -> @@ -8717,7 +8717,7 @@ yeccpars2_380_(__Stack0) -> ? line ( __2 ) ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8720). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8720). -compile({inline,yeccpars2_382_/1}). -file("erl_parse.yrl", 156). yeccpars2_382_(__Stack0) -> @@ -8727,7 +8727,7 @@ yeccpars2_382_(__Stack0) -> [ { type , ? line ( __1 ) , product , [ ] } , __4 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8730). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8730). -compile({inline,yeccpars2_384_/1}). -file("erl_parse.yrl", 121). yeccpars2_384_(__Stack0) -> @@ -8744,7 +8744,7 @@ yeccpars2_388_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8747). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8747). -compile({inline,yeccpars2_390_/1}). -file("erl_parse.yrl", 137). yeccpars2_390_(__Stack0) -> @@ -8753,7 +8753,7 @@ yeccpars2_390_(__Stack0) -> { type , ? line ( __1 ) , record , [ __2 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8756). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8756). -compile({inline,yeccpars2_392_/1}). -file("erl_parse.yrl", 165). yeccpars2_392_(__Stack0) -> @@ -8771,7 +8771,7 @@ yeccpars2_394_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8774). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8774). -compile({inline,yeccpars2_395_/1}). -file("erl_parse.yrl", 138). yeccpars2_395_(__Stack0) -> @@ -8781,7 +8781,7 @@ yeccpars2_395_(__Stack0) -> record , [ __2 | __4 ] } end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8784). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8784). -compile({inline,yeccpars2_398_/1}). -file("erl_parse.yrl", 142). yeccpars2_398_(__Stack0) -> @@ -8799,7 +8799,7 @@ yeccpars2_400_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8802). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8802). -compile({inline,yeccpars2_403_/1}). -file("erl_parse.yrl", 159). yeccpars2_403_(__Stack0) -> @@ -8817,7 +8817,7 @@ yeccpars2_405_(__Stack0) -> lift_unions ( __1 , __3 ) end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8820). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8820). -compile({inline,yeccpars2_407_/1}). -file("erl_parse.yrl", 103). yeccpars2_407_(__Stack0) -> @@ -8835,7 +8835,7 @@ yeccpars2_408_(__Stack0) -> [ __1 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8838). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8838). -compile({inline,yeccpars2_412_/1}). -file("erl_parse.yrl", 109). yeccpars2_412_(__Stack0) -> @@ -8965,7 +8965,7 @@ yeccpars2_440_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8968). +-file("/Users/bjorng/Downloads/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8968). -compile({inline,yeccpars2_441_/1}). -file("erl_parse.yrl", 90). yeccpars2_441_(__Stack0) -> diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 5b2f032afc..ee8ba54cb8 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1539,6 +1539,10 @@ void process_main(void) /* * Skeleton for receive statement: * + * recv_mark L1 Optional + * call make_ref/monitor Optional + * ... + * recv_set L1 Optional * L1: <-------------------+ * <-----------+ | * | | @@ -1557,6 +1561,34 @@ void process_main(void) * */ + OpCase(recv_mark_f): { + /* + * Save the current position in message buffer and the + * the label for the loop_rec/2 instruction for the + * the receive statement. + */ + c_p->msg.mark = (BeamInstr *) Arg(0); + c_p->msg.saved_last = c_p->msg.last; + Next(1); + } + + OpCase(i_recv_set): { + /* + * If the mark is valid (points to the loop_rec/2 + * instruction that follows), we know that the saved + * position points to the first message that could + * possibly be matched out. + * + * If the mark is invalid, we do nothing, meaning that + * we will look through all messages in the message queue. + */ + if (c_p->msg.mark == (BeamInstr *) (I+1)) { + c_p->msg.save = c_p->msg.saved_last; + } + I++; + /* Fall through to the loop_rec/2 instruction */ + } + /* * Pick up the next message and place it in x(0). * If no message, jump to a wait or wait_timeout instruction. diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h index 459c6363aa..489dee7b37 100644 --- a/erts/emulator/beam/erl_message.h +++ b/erts/emulator/beam/erl_message.h @@ -75,6 +75,13 @@ typedef struct { ErlMessage** last; /* point to the last next pointer */ ErlMessage** save; int len; /* queue length */ + + /* + * The following two fields are used by the recv_mark/1 and + * recv_set/1 instructions. + */ + BeamInstr* mark; /* address to rec_loop/2 instruction */ + ErlMessage** saved_last; /* saved last pointer */ } ErlMessageQueue; #ifdef ERTS_SMP @@ -137,6 +144,7 @@ do { \ (p)->msg.len--; \ if (__mp == NULL) \ (p)->msg.last = (p)->msg.save; \ + (p)->msg.mark = 0; \ } while(0) /* Reset message save point (after receive match) */ diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 9e8ac74f40..49280a60e0 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -1421,3 +1421,12 @@ i_gc_bif1 j I s I d # R13B03 # on_load + +# +# R14A. +# +recv_mark f + +recv_set Fail | label Lbl | loop_rec Lf Reg => \ + i_recv_set | label Lbl | loop_rec Lf Reg +i_recv_set diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index df2faf1450..2424fedbed 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -81,6 +81,7 @@ MODULES= \ port_bif_SUITE \ process_SUITE \ pseudoknot_SUITE \ + receive_SUITE \ ref_SUITE \ register_SUITE \ save_calls_SUITE \ diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 8f48d8a992..7c19274696 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -1,23 +1,24 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(distribution_SUITE). +-compile(r12). %% Tests distribution and the tcp driver. diff --git a/erts/emulator/test/fun_r12_SUITE.erl b/erts/emulator/test/fun_r12_SUITE.erl index f21299ba67..9262731dcb 100644 --- a/erts/emulator/test/fun_r12_SUITE.erl +++ b/erts/emulator/test/fun_r12_SUITE.erl @@ -18,6 +18,7 @@ %% -module(fun_r12_SUITE). +-compile(r12). -export([all/1,init_per_testcase/2,fin_per_testcase/2,dist_old_release/1]). diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl new file mode 100644 index 0000000000..40ebf2bd21 --- /dev/null +++ b/erts/emulator/test/receive_SUITE.erl @@ -0,0 +1,113 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(receive_SUITE). + +%% Tests receive after. + +-include("test_server.hrl"). + +-export([all/1, + call_with_huge_message_queue/1,receive_in_between/1]). + +-export([init_per_testcase/2,fin_per_testcase/2]). + +all(suite) -> + [call_with_huge_message_queue,receive_in_between]. + +init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> + Dog=?t:timetrap(?t:minutes(3)), + [{watchdog, Dog}|Config]. + +fin_per_testcase(_Func, Config) -> + Dog=?config(watchdog, Config), + ?t:timetrap_cancel(Dog). + +call_with_huge_message_queue(Config) when is_list(Config) -> + ?line Pid = spawn_link(fun echo_loop/0), + + ?line {Time,ok} = tc(fun() -> calls(10, Pid) end), + + ?line [self() ! {msg,N} || N <- lists:seq(1, 500000)], + erlang:garbage_collect(), + ?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end), + io:format("Time for empty message queue: ~p", [Time]), + io:format("Time for huge message queue: ~p", [NewTime]), + + case (NewTime+1) / (Time+1) of + Q when Q < 10 -> + ok; + Q -> + io:format("Q = ~p", [Q]), + ?line ?t:fail() + end, + ok. + +calls(0, _) -> ok; +calls(N, Pid) -> + {ok,{ultimate_answer,42}} = call(Pid, {ultimate_answer,42}), + calls(N-1, Pid). + +call(Pid, Msg) -> + Mref = erlang:monitor(process, Pid), + Pid ! {Mref,{self(),Msg}}, + receive + {Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + {ok, Reply}; + {'DOWN', Mref, _, _, Reason} -> + exit(Reason) + end. + +receive_in_between(Config) when is_list(Config) -> + ?line Pid = spawn_link(fun echo_loop/0), + ?line [{ok,{a,b}} = call2(Pid, {a,b}) || _ <- lists:seq(1, 100000)], + ok. + +call2(Pid, Msg) -> + self() ! dummy, + Mref = erlang:monitor(process, Pid), + Pid ! {Mref,{self(),Msg}}, + receive_one(), + receive + {Mref,Reply} -> + erlang:demonitor(Mref, [flush]), + {ok,Reply}; + {'DOWN',Mref,_,_,Reason} -> + exit(Reason) + end. + +receive_one() -> + receive + dummy -> ok + end. + +%%% +%%% Common helpers. +%%% + +echo_loop() -> + receive + {Ref,{Pid,Msg}} -> + Pid ! {Ref,Msg}, + echo_loop() + end. + +tc(Fun) -> + timer:tc(erlang, apply, [Fun,[]]). diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile index 70ddd54145..0f6d2f6193 100644 --- a/lib/compiler/src/Makefile +++ b/lib/compiler/src/Makefile @@ -58,6 +58,7 @@ MODULES = \ beam_listing \ beam_opcodes \ beam_peep \ + beam_receive \ beam_trim \ beam_type \ beam_utils \ diff --git a/lib/compiler/src/beam_disasm.erl b/lib/compiler/src/beam_disasm.erl index c956f2f000..9571f817e3 100644 --- a/lib/compiler/src/beam_disasm.erl +++ b/lib/compiler/src/beam_disasm.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2000-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %%======================================================================= %% Notes: @@ -1096,6 +1096,14 @@ resolve_inst({on_load,[]},_,_,_) -> on_load; %% +%% R14A. +%% +resolve_inst({recv_mark,[Lbl]},_,_,_) -> + {recv_mark,Lbl}; +resolve_inst({recv_set,[Lbl]},_,_,_) -> + {recv_set,Lbl}; + +%% %% Catches instructions that are not yet handled. %% resolve_inst(X,_,_,_) -> ?exit({resolve_inst,X}). diff --git a/lib/compiler/src/beam_receive.erl b/lib/compiler/src/beam_receive.erl new file mode 100644 index 0000000000..9ed44ad5d7 --- /dev/null +++ b/lib/compiler/src/beam_receive.erl @@ -0,0 +1,388 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(beam_receive). +-export([module/2]). +-import(lists, [foldl/3,reverse/1,reverse/2]). + +%%% +%%% In code such as: +%%% +%%% Ref = make_ref(), %Or erlang:monitor(process, Pid) +%%% . +%%% . +%%% . +%%% receive +%%% {Ref,Reply} -> Reply +%%% end. +%%% +%%% we know that none of the messages that exist in the message queue +%%% before the call to make_ref/0 can be matched out in the receive +%%% statement. Therefore we can avoid going through the entire message +%%% queue if we introduce two new instructions (here written as +%%% BIFs in pseudo-Erlang): +%%% +%%% recv_mark(SomeUniqInteger), +%%% Ref = make_ref(), +%%% . +%%% . +%%% . +%%% recv_set(SomeUniqInteger), +%%% receive +%%% {Ref,Reply} -> Reply +%%% end. +%%% +%%% The recv_mark/1 instruction will save the current position and +%%% SomeUniqInteger in the process context. The recv_set +%%% instruction will verify that SomeUniqInteger is still stored +%%% in the process context. If it is, it will set the current pointer +%%% for the message queue (the next message to be read out) to the +%%% position that was saved by recv_mark/1. +%%% +%%% The remove_message instruction must be modified to invalidate +%%% the information stored by the previous recv_mark/1, in case there +%%% is another receive executed between the calls to recv_mark/1 and +%%% recv_set/1. +%%% +%%% We use a reference to a label (i.e. a position in the loaded code) +%%% as the SomeUniqInteger. +%%% + +module({Mod,Exp,Attr,Fs0,Lc}, _Opts) -> + Fs = [function(F) || F <- Fs0], + Code = {Mod,Exp,Attr,Fs,Lc}, + {ok,Code}. + +%%% +%%% Local functions. +%%% + +function({function,Name,Arity,Entry,Is}) -> + try + D = beam_utils:index_labels(Is), + {function,Name,Arity,Entry,opt(Is, D, [])} + catch + Class:Error -> + Stack = erlang:get_stacktrace(), + io:fwrite("Function: ~w/~w\n", [Name,Arity]), + erlang:raise(Class, Error, Stack) + end. + +opt([{call_ext,Arity,{extfunc,erlang,Name,Arity}}=I|Is0], D, Acc) -> + case creates_new_ref(Name, Arity) of + true -> + %% The call creates a brand new reference. Now + %% search for a receive statement in the same + %% function that will match against the reference. + case opt_recv(Is0, D) of + no -> + opt(Is0, D, [I|Acc]); + {yes,Is,Lbl} -> + opt(Is, D, [I,{recv_mark,{f,Lbl}}|Acc]) + end; + false -> + opt(Is0, D, [I|Acc]) + end; +opt([I|Is], D, Acc) -> + opt(Is, D, [I|Acc]); +opt([], _, Acc) -> + reverse(Acc). + +%% creates_new_ref(Name, Arity) -> true|false. +%% Return 'true' if the BIF Name/Arity will create a new reference. +creates_new_ref(monitor, 2) -> true; +creates_new_ref(make_ref, 0) -> true; +creates_new_ref(_, _) -> false. + +%% opt_recv([Instruction], LabelIndex) -> no|{yes,[Instruction]} +%% Search for a receive statement that will only retrieve messages +%% that contain the newly created reference (which is currently in {x,0}). +opt_recv(Is, D) -> + R = regs_init_x0(), + L = gb_sets:empty(), + opt_recv(Is, D, R, L, []). + +opt_recv([{label,L}=Lbl,{loop_rec,{f,Fail},_}=Loop|Is], D, R0, _, Acc) -> + R = regs_kill_not_live(0, R0), + case regs_to_list(R) of + [{y,_}=RefReg] -> + %% We now have the new reference in the Y register RefReg + %% and the current instruction is the beginning of a + %% receive statement. We must now verify that only messages + %% that contain the reference will be matched. + case opt_ref_used(Is, RefReg, Fail, D) of + false -> + no; + true -> + RecvSet = {recv_set,{f,L}}, + {yes,reverse(Acc, [RecvSet,Lbl,Loop|Is]),L} + end; + [] -> + no + end; +opt_recv([I|Is], D, R0, L0, Acc) -> + {R,L} = opt_update_regs(I, R0, L0), + case regs_empty(R) of + true -> + %% The reference is no longer alive. There is no + %% point in continuing the search. + no; + false -> + opt_recv(Is, D, R, L, [I|Acc]) + end. + +opt_update_regs({block,Bl}, R, L) -> + {opt_update_regs_bl(Bl, R),L}; +opt_update_regs({call,_,_}, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({call_ext,_,_}, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({call_fun,_}, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({kill,Y}, R, L) -> + {regs_kill([Y], R),L}; +opt_update_regs(send, R, L) -> + {regs_kill_not_live(0, R),L}; +opt_update_regs({'catch',_,{f,Lbl}}, R, L) -> + {R,gb_sets:add(Lbl, L)}; +opt_update_regs({catch_end,_}, R, L) -> + {R,L}; +opt_update_regs({label,Lbl}, R, L) -> + case gb_sets:is_member(Lbl, L) of + false -> + %% We can't allow arbitrary labels (since the receive + %% could be entered without first creating the reference). + {regs_init(),L}; + true -> + %% A catch label for a previously seen catch instruction is OK. + {R,L} + end; +opt_update_regs({try_end,_}, R, L) -> + {R,L}; +opt_update_regs(_I, _R, L) -> + %% Unrecognized instruction. Abort the search. + {regs_init(),L}. + +opt_update_regs_bl([{set,Ds,_,{alloc,Live,_}}|Is], Regs0) -> + Regs1 = regs_kill_not_live(Live, Regs0), + Regs = regs_kill(Ds, Regs1), + opt_update_regs_bl(Is, Regs); +opt_update_regs_bl([{set,[Dst]=Ds,[Src],move}|Is], Regs0) -> + Regs1 = regs_kill(Ds, Regs0), + Regs = case regs_is_member(Src, Regs1) of + false -> Regs1; + true -> regs_add(Dst, Regs1) + end, + opt_update_regs_bl(Is, Regs); +opt_update_regs_bl([{set,Ds,_,_}|Is], Regs0) -> + Regs = regs_kill(Ds, Regs0), + opt_update_regs_bl(Is, Regs); +opt_update_regs_bl([], Regs) -> Regs. + +%% opt_ref_used([Instruction], RefRegister, FailLabel, LabelIndex) -> true|false +%% Return 'true' if it is certain that only messages that contain the same +%% reference as in RefRegister can be matched out. Otherwise return 'false'. +%% +%% Basically, we follow all possible paths through the receive statement. +%% If all paths are safe, we return 'true'. +%% +%% A branch to FailLabel is safe, because it exits the receive statement +%% and no further message may be matched out. +%% +%% If a path hits an comparision between RefRegister and part of the message, +%% that path is safe (any messages that may be matched further down the +%% path is guaranteed to contain the reference). +%% +%% Otherwise, if we hit a 'remove_message' instruction, we give up +%% and return 'false' (the optimization is definitely unsafe). If +%% we hit an unrecognized instruction, we also give up and return +%% 'false' (the optimization may be unsafe). + +opt_ref_used(Is, RefReg, Fail, D) -> + Done = gb_sets:singleton(Fail), + Regs = regs_init_x0(), + try + opt_ref_used_1(Is, RefReg, D, Done, Regs), + true + catch + throw:not_used -> + false + end. + +%% This functions only returns if all paths through the receive +%% statement are safe, and throws an 'not_used' term otherwise. +opt_ref_used_1([{block,Bl}|Is], RefReg, D, Done, Regs0) -> + Regs = opt_ref_used_bl(Bl, Regs0), + opt_ref_used_1(Is, RefReg, D, Done, Regs); +opt_ref_used_1([{test,is_eq_exact,{f,Fail},Args}|Is], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_at(Fail, RefReg, D, Done0, Regs), + case is_ref_msg_comparison(Args, RefReg, Regs) of + false -> + opt_ref_used_1(Is, RefReg, D, Done, Regs); + true -> + %% The instructions that follow (Is) can only be executed + %% if the message contains the same reference as in RefReg. + Done + end; +opt_ref_used_1([{test,is_ne_exact,{f,Fail},Args}|Is], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_1(Is, RefReg, D, Done0, Regs), + case is_ref_msg_comparison(Args, RefReg, Regs) of + false -> + opt_ref_used_at(Fail, RefReg, D, Done, Regs); + true -> + Done + end; +opt_ref_used_1([{test,_,{f,Fail},_}|Is], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_at(Fail, RefReg, D, Done0, Regs), + opt_ref_used_1(Is, RefReg, D, Done, Regs); +opt_ref_used_1([{select_tuple_arity,_,{f,Fail},{list,List}}|_], RefReg, D, Done, Regs) -> + Lbls = [F || {f,F} <- List] ++ [Fail], + opt_ref_used_in_all(Lbls, RefReg, D, Done, Regs); +opt_ref_used_1([{select_val,_,{f,Fail},{list,List}}|_], RefReg, D, Done, Regs) -> + Lbls = [F || {f,F} <- List] ++ [Fail], + opt_ref_used_in_all(Lbls, RefReg, D, Done, Regs); +opt_ref_used_1([{label,Lbl}|Is], RefReg, D, Done, Regs) -> + case gb_sets:is_member(Lbl, Done) of + true -> Done; + false -> opt_ref_used_1(Is, RefReg, D, Done, Regs) + end; +opt_ref_used_1([{loop_rec_end,_}|_], _, _, Done, _) -> + Done; +opt_ref_used_1([_I|_], _RefReg, _D, _Done, _Regs) -> + %% The optimization may be unsafe. + throw(not_used). + +%% is_ref_msg_comparison(Args, RefReg, RegisterSet) -> true|false. +%% Return 'true' if Args denotes a comparison between the +%% reference and message or part of the message. +is_ref_msg_comparison([R,RefReg], RefReg, Regs) -> + regs_is_member(R, Regs); +is_ref_msg_comparison([RefReg,R], RefReg, Regs) -> + regs_is_member(R, Regs); +is_ref_msg_comparison([_,_], _, _) -> false. + +opt_ref_used_in_all([L|Ls], RefReg, D, Done0, Regs) -> + Done = opt_ref_used_at(L, RefReg, D, Done0, Regs), + opt_ref_used_in_all(Ls, RefReg, D, Done, Regs); +opt_ref_used_in_all([], _, _, Done, _) -> Done. + +opt_ref_used_at(Fail, RefReg, D, Done0, Regs) -> + case gb_sets:is_member(Fail, Done0) of + true -> + Done0; + false -> + Is = beam_utils:code_at(Fail, D), + Done = opt_ref_used_1(Is, RefReg, D, Done0, Regs), + gb_sets:add(Fail, Done) + end. + +opt_ref_used_bl([{set,[],[],remove_message}|_], _) -> + %% We have proved that a message that does not depend on the + %% reference can be matched out. + throw(not_used); +opt_ref_used_bl([{set,Ds,Ss,_}|Is], Regs0) -> + case regs_all_members(Ss, Regs0) of + false -> + %% The destination registers may be assigned values that + %% are not dependent on the message being matched. + Regs = regs_kill(Ds, Regs0), + opt_ref_used_bl(Is, Regs); + true -> + %% All the sources depend on the message directly or + %% indirectly. + Regs = regs_add_list(Ds, Regs0), + opt_ref_used_bl(Is, Regs) + end; +opt_ref_used_bl([], Regs) -> Regs. + +%%% +%%% Functions for keeping track of a set of registers. +%%% + +%% regs_init() -> RegisterSet +%% Return an empty set of registers. + +regs_init() -> + {0,0}. + +%% regs_init_x0() -> RegisterSet +%% Return a set that only contains the {x,0} register. + +regs_init_x0() -> + {1 bsl 0,0}. + +%% regs_empty(Register) -> true|false +%% Test whether the register set is empty. + +regs_empty(R) -> + R =:= {0,0}. + +%% regs_kill_not_live(Live, RegisterSet) -> RegisterSet' +%% Kill all registers indicated not live by Live. + +regs_kill_not_live(Live, {Xregs,Yregs}) -> + {Xregs band ((1 bsl Live)-1),Yregs}. + +%% regs_kill([Register], RegisterSet) -> RegisterSet' +%% Kill all registers mentioned in the list of registers. + +regs_kill([{x,N}|Rs], {Xregs,Yregs}) -> + regs_kill(Rs, {Xregs band (bnot (1 bsl N)),Yregs}); +regs_kill([{y,N}|Rs], {Xregs,Yregs}) -> + regs_kill(Rs, {Xregs,Yregs band (bnot (1 bsl N))}); +regs_kill([{fr,_}|Rs], Regs) -> + regs_kill(Rs, Regs); +regs_kill([], Regs) -> Regs. + +regs_add_list(List, Regs) -> + foldl(fun(R, A) -> regs_add(R, A) end, Regs, List). + +%% regs_add(Register, RegisterSet) -> RegisterSet' +%% Add a new register to the set of registers. + +regs_add({x,N}, {Xregs,Yregs}) -> + {Xregs bor (1 bsl N),Yregs}; +regs_add({y,N}, {Xregs,Yregs}) -> + {Xregs,Yregs bor (1 bsl N)}. + +%% regs_all_members([Register], RegisterSet) -> true|false +%% Test whether all of the registers are part of the register set. + +regs_all_members([R|Rs], Regs) -> + regs_is_member(R, Regs) andalso regs_all_members(Rs, Regs); +regs_all_members([], _) -> true. + +%% regs_is_member(Register, RegisterSet) -> true|false +%% Test whether Register is part of the register set. + +regs_is_member({x,N}, {Regs,_}) -> Regs band (1 bsl N) =/= 0; +regs_is_member({y,N}, {_,Regs}) -> Regs band (1 bsl N) =/= 0; +regs_is_member(_, _) -> false. + +%% regs_to_list(RegisterSet) -> [Register] +%% Convert the register set to an explicit list of registers. +regs_to_list({Xregs,Yregs}) -> + regs_to_list_1(Xregs, 0, x, regs_to_list_1(Yregs, 0, y, [])). + +regs_to_list_1(0, _, _, Acc) -> + Acc; +regs_to_list_1(Regs, N, Tag, Acc) when (Regs band 1) =:= 1 -> + regs_to_list_1(Regs bsr 1, N+1, Tag, [{Tag,N}|Acc]); +regs_to_list_1(Regs, N, Tag, Acc) -> + regs_to_list_1(Regs bsr 1, N+1, Tag, Acc). diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 1fd61831e0..34065cfdce 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -416,6 +416,11 @@ valfun_1({put,Src}, Vst) -> valfun_1({put_string,Sz,_,Dst}, Vst0) when is_integer(Sz) -> Vst = eat_heap(2*Sz, Vst0), set_type_reg(cons, Dst, Vst); +%% Instructions for optimization of selective receives. +valfun_1({recv_mark,{f,Fail}}, Vst) when is_integer(Fail) -> + Vst; +valfun_1({recv_set,{f,Fail}}, Vst) when is_integer(Fail) -> + Vst; %% Misc. valfun_1({'%live',Live}, Vst) -> verify_live(Live, Vst), diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 5017fd2c23..3f250a6d5a 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -162,6 +162,10 @@ expand_opt(report, Os) -> [report_errors,report_warnings|Os]; expand_opt(return, Os) -> [return_errors,return_warnings|Os]; +expand_opt(r12, Os) -> + [no_recv_opt|Os]; +expand_opt(r13, Os) -> + [no_recv_opt|Os]; expand_opt({debug_info_key,_}=O, Os) -> [encrypt_debug_info,O|Os]; expand_opt(no_float_opt, Os) -> @@ -621,6 +625,8 @@ asm_passes() -> {iff,dclean,{listing,"clean"}}, {unless,no_bsm_opt,{pass,beam_bsm}}, {iff,dbsm,{listing,"bsm"}}, + {unless,no_recv_opt,{pass,beam_receive}}, + {iff,drecv,{listing,"recv"}}, {unless,no_stack_trimming,{pass,beam_trim}}, {iff,dtrim,{listing,"trim"}}, {pass,beam_flatten}]}, diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src index b0311365c4..4ac879c9a4 100644 --- a/lib/compiler/src/compiler.app.src +++ b/lib/compiler/src/compiler.app.src @@ -1,19 +1,19 @@ % This is an -*- erlang -*- file. %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% {application, compiler, @@ -33,6 +33,7 @@ beam_listing, beam_opcodes, beam_peep, + beam_receive, beam_trim, beam_type, beam_utils, diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab index 47e6e72402..b57508ea8e 100644 --- a/lib/compiler/src/genop.tab +++ b/lib/compiler/src/genop.tab @@ -274,3 +274,8 @@ BEAM_FORMAT_NUMBER=0 # R13B03 149: on_load/0 + +# R14A + +150: recv_mark/1 +151: recv_set/1 diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 7c3990a855..e1cc5dafb5 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(compile_SUITE). @@ -625,7 +625,7 @@ core(Config) when is_list(Config) -> {raw_abstract_v1,Abstr}}]}} = beam_lib:chunks(Beam, [abstract_code]), {Mod,Abstr} end || Beam <- TestBeams], - ?line Res = p_run(fun(F) -> do_core(F, Outdir) end, Abstr), + ?line Res = test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr), ?line test_server:timetrap_cancel(Dog), Res. @@ -661,7 +661,7 @@ asm(Config) when is_list(Config) -> ?line Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"), ?line TestBeams = filelib:wildcard(Wc), - ?line Res = p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams), + ?line Res = test_lib:p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams), ?line test_server:timetrap_cancel(Dog), Res. @@ -688,35 +688,3 @@ do_asm(Beam, Outdir) -> [M,Class,Error,erlang:get_stacktrace()]), error end. - -%% p_run(fun() -> ok|error, List) -> ok -%% Will fail the test case if there were any errors. - -p_run(Test, List) -> - N = erlang:system_info(schedulers) + 1, - p_run_loop(Test, List, N, [], 0, 0). - -p_run_loop(_, [], _, [], Errors, Ws) -> - case Errors of - 0 -> - case Ws of - 0 -> ok; - 1 -> {comment,"1 core_lint failure"}; - N -> {comment,integer_to_list(N)++" core_lint failures"} - end; - N -> ?t:fail({N,errors}) - end; -p_run_loop(Test, [H|T], N, Refs, Errors, Ws) when length(Refs) < N -> - {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end), - p_run_loop(Test, T, N, [Ref|Refs], Errors, Ws); -p_run_loop(Test, List, N, Refs0, Errors0, Ws0) -> - receive - {'DOWN',Ref,process,_,Res} -> - {Errors,Ws} = case Res of - ok -> {Errors0,Ws0}; - error -> {Errors0+1,Ws0}; - warning -> {Errors0,Ws0+1} - end, - Refs = Refs0 -- [Ref], - p_run_loop(Test, List, N, Refs, Errors, Ws) - end. diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl index e096571d50..c015af788b 100644 --- a/lib/compiler/test/misc_SUITE.erl +++ b/lib/compiler/test/misc_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(misc_SUITE). @@ -154,6 +154,17 @@ silly_coverage(Config) when is_list(Config) -> {test,bs_get_binary2,{f,99},0,[{x,0},{atom,all},1,[]],{x,0}}, {block,[a|b]}]}],0}, ?line expect_error(fun() -> beam_bsm:module(BsmInput, []) end), + + %% beam_receive. + ReceiveInput = {?MODULE,[{foo,0}],[], + [{function,foo,0,2, + [{label,1}, + {func_info,{atom,?MODULE},{atom,foo},0}, + {label,2}, + {call_ext,0,{extfunc,erlang,make_ref,0}}, + {block,[a|b]}]}],0}, + ?line expect_error(fun() -> beam_receive:module(ReceiveInput, []) end), + ok. expect_error(Fun) -> diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl index cb8833759a..fca3f0387b 100644 --- a/lib/compiler/test/receive_SUITE.erl +++ b/lib/compiler/test/receive_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %%% Purpose : Compiles various modules with tough code @@ -21,7 +21,7 @@ -module(receive_SUITE). -export([all/1,init_per_testcase/2,fin_per_testcase/2, - recv/1,coverage/1,otp_7980/1]). + recv/1,coverage/1,otp_7980/1,ref_opt/1]). -include("test_server.hrl"). @@ -36,7 +36,7 @@ fin_per_testcase(_Case, Config) -> all(suite) -> test_lib:recompile(?MODULE), - [recv,coverage,otp_7980]. + [recv,coverage,otp_7980,ref_opt]. -record(state, {ena = true}). @@ -157,5 +157,52 @@ otp_7980_add_clients(Count) -> end, N - 1 end, Count, [1,2,3]). - + +ref_opt(Config) when is_list(Config) -> + case ?MODULE of + receive_SUITE -> ref_opt_1(Config); + _ -> {skip,"Enough to run this case once."} + end. + +ref_opt_1(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line PrivDir = ?config(priv_dir, Config), + ?line Sources = filelib:wildcard(filename:join([DataDir,"ref_opt","*.erl"])), + ?line test_lib:p_run(fun(Src) -> + do_ref_opt(Src, PrivDir) + end, Sources), + ok. + +do_ref_opt(Source, PrivDir) -> + try + {ok,Mod} = c:c(Source, [{outdir,PrivDir}]), + ok = Mod:Mod(), + Base = filename:rootname(filename:basename(Source), ".erl"), + BeamFile = filename:join(PrivDir, Base), + {beam_file,Mod,_,_,_,Code} = beam_disasm:file(BeamFile), + case Base of + "no_"++_ -> + [] = collect_recv_opt_instrs(Code); + "yes_"++_ -> + [{recv_mark,{f,L}},{recv_set,{f,L}}] = + collect_recv_opt_instrs(Code) + end, + ok + catch Class:Error -> + io:format("~s: ~p ~p\n~p\n", + [Source,Class,Error,erlang:get_stacktrace()]), + error + end. + +collect_recv_opt_instrs(Code) -> + L = [ [I || I <- Is, + begin + case I of + {recv_mark,{f,_}} -> true; + {recv_set,{f,_}} -> true; + _ -> false + end + end] || {function,_,_,_,Is} <- Code], + lists:append(L). + id(I) -> I. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl new file mode 100644 index 0000000000..bc63dac437 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl @@ -0,0 +1,99 @@ +-module(no_1). +-compile(export_all). + +?MODULE() -> + ok. + +f1(X) -> + Ref = make_ref(), + receive + _ when [X] =:= Ref -> + ok + end. + +f2(X, Y) -> + _Ref = make_ref(), + receive + _ when X =:= Y -> + ok + end. + +f3(X) -> + Ref = make_ref(), + receive + _ when X =:= Ref -> + ok + end. + +f4(X) -> + Ref = make_ref(), + receive + {X,_} when not X =:= Ref -> + ok + end. + +f5(X) -> + Ref = make_ref(), + receive + {Y,_} when X =:= Y; Y =:= Ref -> + ok + end. + +f6(X) -> + Ref = make_ref(), + receive + {Y,_} when Y =:= Ref; Ref =:= X -> + ok + end. + +f7(X) -> + Ref = make_ref(), + receive + {Y,_} when Y =:= Ref; not (X =:= Ref) -> + ok + end. + +f8(X) -> + Ref = make_ref(), + receive + {Y,_} when not (X =:= Ref); Y =:= Ref -> + ok + end. + +f9(X) -> + Ref = make_ref(), + receive + {Y,_} when (not (X =:= Ref)) or (Y =:= Ref) -> + ok + end. + +f10(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when not (X =:= Y andalso Z =:= Ref) -> + ok + end. + +f11(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when not ((X =:= Y) and (Z =:= Ref)) -> + ok + end. + +f12(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when not ((Z =:= Ref) and (X =:= Y)) -> + ok + end. + +f13() -> + Ref = make_ref(), + RefCopy = id(Ref), + receive + _ when hd([RefCopy]) =:= Ref -> + ok + end. + +id(I) -> I. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl new file mode 100644 index 0000000000..bc8d30c2ac --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl @@ -0,0 +1,26 @@ +-module(no_2). +-compile(export_all). + +?MODULE() -> + ok. + +f1() -> + Ref = make_ref(), + receive + {'DOWN',Ref} -> + ok; + {'DOWN',_} -> + ok + end. + +f2(Pid, Msg) -> + Ref = erlang:monitor(process, Pid), + Pid ! Msg, + receive + {ok,Ref,Reply} -> + {ok,Reply}; + {error,Ref,Reply} -> + {error,Reply}; + {error,A,B} -> + {error,A,B} + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl new file mode 100644 index 0000000000..44cf8d7f71 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl @@ -0,0 +1,14 @@ +-module(no_3). +-compile(export_all). + +?MODULE() -> + ok. + +f(X) -> + Ref = case X of + false -> ref; + true -> make_ref() + end, + receive + Ref -> ok + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl new file mode 100644 index 0000000000..e2ebe234c1 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl @@ -0,0 +1,12 @@ +-module(yes_1). +-compile(export_all). + +?MODULE() -> + ok. + +f() -> + Ref = make_ref(), + receive + {Ref,Reply} -> + Reply + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl new file mode 100644 index 0000000000..6077cdcab9 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl @@ -0,0 +1,13 @@ +-module(yes_2). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = make_ref(), + Pid ! Msg, + receive + {Ref,Reply} -> + Reply + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl new file mode 100644 index 0000000000..28efc542ae --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl @@ -0,0 +1,16 @@ +-module(yes_3). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = make_ref(), + do_send(Pid, Msg), + receive + {Ref,Reply} -> + Reply + end. + +do_send(Pid, Msg) -> + Pid ! Msg. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl new file mode 100644 index 0000000000..d1ba4832c7 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl @@ -0,0 +1,16 @@ +-module(yes_4). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = make_ref(), + catch do_send(Pid, Msg), + receive + {Ref,Reply} -> + Reply + end. + +do_send(Pid, Msg) -> + Pid ! Msg. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl new file mode 100644 index 0000000000..3f02fba6a6 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl @@ -0,0 +1,46 @@ +-module(yes_5). +-compile(export_all). + +?MODULE() -> + ok. + +do_call(Process, Label, Request, Timeout) -> + Node = case Process of + {_S, N} when is_atom(N) -> + N; + _ when is_pid(Process) -> + node(Process) + end, + try erlang:monitor(process, Process) of + Mref -> + catch erlang:send(Process, {Label, {self(), Mref}, Request}, + [noconnect]), + receive + {Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + {ok, Reply}; + {'DOWN', Mref, _, _, noconnection} -> + exit({nodedown, Node}); + {'DOWN', Mref, _, _, Reason} -> + exit(Reason) + after Timeout -> + erlang:demonitor(Mref), + receive + {'DOWN', Mref, _, _, _} -> true + after 0 -> true + end, + exit(timeout) + end + catch + error:_ -> + monitor_node(Node, true), + receive + {nodedown, Node} -> + monitor_node(Node, false), + exit({nodedown, Node}) + after 0 -> + Tag = make_ref(), + Process ! {Label, {self(), Tag}, Request}, + ?MODULE:wait_resp(Node, Tag, Timeout) + end + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl new file mode 100644 index 0000000000..c54b636aa6 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl @@ -0,0 +1,15 @@ +-module(yes_6). +-compile(export_all). + +?MODULE() -> + ok. + +f(Pid, Msg) -> + Ref = erlang:monitor(process, Pid), + Pid ! Msg, + receive + {ok,Ref,Reply} -> + {ok,Reply}; + {error,Ref,Reply} -> + {error,Reply} + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl new file mode 100644 index 0000000000..849eab1746 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl @@ -0,0 +1,12 @@ +-module(yes_7). +-compile(export_all). + +?MODULE() -> + ok. + +f(X, Y) -> + Ref = make_ref(), + receive + {Z,_} when X =:= Y, Ref =:= Z -> + ok + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl new file mode 100644 index 0000000000..a47fe8cfbf --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl @@ -0,0 +1,15 @@ +-module(yes_8). +-compile(export_all). + +?MODULE() -> + ok. + +%% Cover use of floating point registers. + +f(Pid, X) when is_float(X) -> + Ref = make_ref(), + Pid ! {X+3}, + receive + Ref -> + ok + end. diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl new file mode 100644 index 0000000000..97fce5e734 --- /dev/null +++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl @@ -0,0 +1,13 @@ +-module(yes_9). +-compile(export_all). + +?MODULE() -> + ok. + +f(Fun) -> + Ref = make_ref(), + Fun(), + receive + {Ref,Reply} -> + Reply + end. diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl index 844bbfc4b9..05236ee010 100644 --- a/lib/compiler/test/test_lib.erl +++ b/lib/compiler/test/test_lib.erl @@ -20,7 +20,7 @@ -include("test_server.hrl"). --export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1]). +-export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1,p_run/2]). recompile(Mod) when is_atom(Mod) -> case whereis(cover_server) of @@ -72,3 +72,35 @@ get_data_dir(Config) -> {ok,Data2,_} = regexp:sub(Data1, "_post_opt_SUITE", "_SUITE"), {ok,Data,_} = regexp:sub(Data2, "_inline_SUITE", "_SUITE"), Data. + +%% p_run(fun(Data) -> ok|error, List) -> ok +%% Will fail the test case if there were any errors. + +p_run(Test, List) -> + N = erlang:system_info(schedulers) + 1, + p_run_loop(Test, List, N, [], 0, 0). + +p_run_loop(_, [], _, [], Errors, Ws) -> + case Errors of + 0 -> + case Ws of + 0 -> ok; + 1 -> {comment,"1 warning"}; + N -> {comment,integer_to_list(N)++" warnings"} + end; + N -> ?t:fail({N,errors}) + end; +p_run_loop(Test, [H|T], N, Refs, Errors, Ws) when length(Refs) < N -> + {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end), + p_run_loop(Test, T, N, [Ref|Refs], Errors, Ws); +p_run_loop(Test, List, N, Refs0, Errors0, Ws0) -> + receive + {'DOWN',Ref,process,_,Res} -> + {Errors,Ws} = case Res of + ok -> {Errors0,Ws0}; + error -> {Errors0+1,Ws0}; + warning -> {Errors0,Ws0+1} + end, + Refs = Refs0 -- [Ref], + p_run_loop(Test, List, N, Refs, Errors, Ws) + end. diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl index 3923e98673..a7318e33e8 100644 --- a/lib/hipe/icode/hipe_beam_to_icode.erl +++ b/lib/hipe/icode/hipe_beam_to_icode.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %%======================================================================= @@ -431,6 +431,11 @@ trans_fun([{wait_timeout,{_,Lbl},Reg}|Instructions], Env) -> SuspTmout = hipe_icode:mk_if(suspend_msg_timeout,[], map_label(Lbl),hipe_icode:label_name(DoneLbl)), Movs ++ [SetTmout, SuspTmout, DoneLbl | trans_fun(Instructions,Env1)]; +%%--- mark_recv/1 & mark_set/1 --- +trans_fun([{mark_recv,{f,_}}|Instructions], Env) -> + trans_fun(Instructions,Env); +trans_fun([{mark_set,{f,_}}|Instructions], Env) -> + trans_fun(Instructions,Env); %%-------------------------------------------------------------------- %%--- Translation of arithmetics {bif,ArithOp, ...} --- %%-------------------------------------------------------------------- diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index 5aab547644..43df6f621d 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(gen). @@ -212,7 +212,22 @@ do_call(Process, Label, Request, Timeout) -> catch erlang:send(Process, {Label, {self(), Mref}, Request}, [noconnect]), - wait_resp_mon(Node, Mref, Timeout) + receive + {Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + {ok, Reply}; + {'DOWN', Mref, _, _, noconnection} -> + exit({nodedown, Node}); + {'DOWN', Mref, _, _, Reason} -> + exit(Reason) + after Timeout -> + erlang:demonitor(Mref), + receive + {'DOWN', Mref, _, _, _} -> true + after 0 -> true + end, + exit(timeout) + end catch error:_ -> %% Node (C/Java?) is not supporting the monitor. @@ -233,24 +248,6 @@ do_call(Process, Label, Request, Timeout) -> end end. -wait_resp_mon(Node, Mref, Timeout) -> - receive - {Mref, Reply} -> - erlang:demonitor(Mref, [flush]), - {ok, Reply}; - {'DOWN', Mref, _, _, noconnection} -> - exit({nodedown, Node}); - {'DOWN', Mref, _, _, Reason} -> - exit(Reason) - after Timeout -> - erlang:demonitor(Mref), - receive - {'DOWN', Mref, _, _, _} -> true - after 0 -> true - end, - exit(timeout) - end. - wait_resp(Node, Tag, Timeout) -> receive {Tag, Reply} -> diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl index 6efdce78a1..0f60c2c4ee 100644 --- a/lib/stdlib/test/gen_server_SUITE.erl +++ b/lib/stdlib/test/gen_server_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(gen_server_SUITE). @@ -30,7 +30,8 @@ call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1, spec_init_local_registered_parent/1, spec_init_global_registered_parent/1, - otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1 + otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1, + call_with_huge_message_queue/1 ]). % spawn export @@ -51,7 +52,8 @@ all(suite) -> call_remote_n2, call_remote_n3, spec_init, spec_init_local_registered_parent, spec_init_global_registered_parent, - otp_5854, hibernate, otp_7669, call_format_status]. + otp_5854, hibernate, otp_7669, call_format_status, + call_with_huge_message_queue]. -define(default_timeout, ?t:minutes(1)). @@ -904,6 +906,45 @@ call_format_status(Config) when is_list(Config) -> ?line [format_status_called | _] = lists:reverse(Data2), ok. +%% Test that the time for a huge message queue is not +%% significantly slower than with an empty message queue. +call_with_huge_message_queue(Config) when is_list(Config) -> + ?line Pid = spawn_link(fun echo_loop/0), + + ?line {Time,ok} = tc(fun() -> calls(10, Pid) end), + + ?line [self() ! {msg,N} || N <- lists:seq(1, 500000)], + erlang:garbage_collect(), + ?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end), + io:format("Time for empty message queue: ~p", [Time]), + io:format("Time for huge message queue: ~p", [NewTime]), + + case (NewTime+1) / (Time+1) of + Q when Q < 10 -> + ok; + Q -> + io:format("Q = ~p", [Q]), + ?line ?t:fail() + end, + ok. + +calls(0, _) -> ok; +calls(N, Pid) -> + {ultimate_answer,42} = call(Pid, {ultimate_answer,42}), + calls(N-1, Pid). + +call(Pid, Msg) -> + gen_server:call(Pid, Msg, infinity). + +tc(Fun) -> + timer:tc(erlang, apply, [Fun,[]]). + +echo_loop() -> + receive + {'$gen_call',{Pid,Ref},Msg} -> + Pid ! {Ref,Msg}, + echo_loop() + end. %%-------------------------------------------------------------- %% Help functions to spec_init_* diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 93159fbd5b..d9672a8c7b 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -17,6 +17,7 @@ %% %CopyrightEnd% %% -module(io_proto_SUITE). +-compile(r12). -export([all/1]). diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index ff11ebc6bf..aa12ed57da 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -1,25 +1,26 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %%%---------------------------------------------------------------- %%% Purpose:Test Suite for the 'qlc' module. %%%----------------------------------------------------------------- -module(qlc_SUITE). +-compile(r12). -define(QLC, qlc). -define(QLCs, "qlc"). diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl index 32886b6765..49025b1a3d 100644 --- a/lib/test_server/src/test_server_node.erl +++ b/lib/test_server/src/test_server_node.erl @@ -17,6 +17,7 @@ %% %CopyrightEnd% %% -module(test_server_node). +-compile(r12). %%% %%% The same compiled code for this module must be possible to load |