| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 const intptr_t kNumInputs = 1; | 35 const intptr_t kNumInputs = 1; |
| 36 const intptr_t kNumTemps = 1; | 36 const intptr_t kNumTemps = 1; |
| 37 LocationSummary* locs = | 37 LocationSummary* locs = |
| 38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 39 locs->set_in(0, Location::RegisterLocation(EAX)); | 39 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 40 locs->set_temp(0, Location::RegisterLocation(EDX)); | 40 locs->set_temp(0, Location::RegisterLocation(EDX)); |
| 41 return locs; | 41 return locs; |
| 42 } | 42 } |
| 43 | 43 |
| 44 | 44 |
| 45 // Attempt optimized compilation at return instruction instead of at the entry. |
| 46 // The entry needs to be patchable, no inlined objects are allowed in the area |
| 47 // that will be overwritten by the patch instruction: a jump). |
| 45 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 48 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 49 const Function& function = |
| 50 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| 46 Register result = locs()->in(0).reg(); | 51 Register result = locs()->in(0).reg(); |
| 47 Register func_reg = locs()->temp(0).reg(); | 52 Register func_reg = locs()->temp(0).reg(); |
| 48 ASSERT(result == EAX); | 53 ASSERT(result == EAX); |
| 49 if (!compiler->is_optimizing()) { | 54 if (compiler->is_optimizing()) { |
| 50 // Count only in unoptimized code. | 55 if (compiler->may_reoptimize()) { |
| 51 // TODO(srdjan): Replace the counting code with a type feedback | 56 // Increment of counter occurs only in optimized IC calls, as they |
| 52 // collection and counting stub. | 57 // can cause reoptimization. |
| 53 const Function& function = | 58 Label done; |
| 54 Function::ZoneHandle(compiler->parsed_function().function().raw()); | 59 __ LoadObject(func_reg, function); |
| 60 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), |
| 61 Immediate(FLAG_optimization_counter_threshold)); |
| 62 __ j(LESS, &done, Assembler::kNearJump); |
| 63 // Equal (or greater), optimize. Note that counter can reach equality |
| 64 // only at return instruction. |
| 65 // The stub call preserves result register (EAX). |
| 66 ASSERT(func_reg == EDX); |
| 67 compiler->GenerateCall(0, // no token position. |
| 68 &StubCode::OptimizeFunctionLabel(), |
| 69 PcDescriptors::kOther, |
| 70 locs()); |
| 71 __ Bind(&done); |
| 72 } |
| 73 } else { |
| 55 __ LoadObject(func_reg, function); | 74 __ LoadObject(func_reg, function); |
| 56 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | 75 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
| 57 if (FlowGraphCompiler::CanOptimize() && | 76 if (FlowGraphCompiler::CanOptimize() && |
| 58 compiler->parsed_function().function().is_optimizable()) { | 77 compiler->parsed_function().function().is_optimizable()) { |
| 59 // Do not optimize if usage count must be reported. | 78 // Do not optimize if usage count must be reported. |
| 60 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), | 79 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), |
| 61 Immediate(FLAG_optimization_counter_threshold)); | 80 Immediate(FLAG_optimization_counter_threshold)); |
| 62 Label not_yet_hot; | 81 Label not_yet_hot; |
| 63 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); | 82 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); |
| 64 // Equal (or greater), optimize. | 83 // Equal (or greater), optimize. |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 362 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 344 Label check_identity; | 363 Label check_identity; |
| 345 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); | 364 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); |
| 346 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 365 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 347 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); | 366 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); |
| 348 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 367 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 349 | 368 |
| 350 ICData& equality_ic_data = ICData::ZoneHandle(); | 369 ICData& equality_ic_data = ICData::ZoneHandle(); |
| 351 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | 370 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
| 352 ASSERT(!original_ic_data.IsNull()); | 371 ASSERT(!original_ic_data.IsNull()); |
| 353 equality_ic_data = original_ic_data.AsUnaryClassChecks(); | 372 if (original_ic_data.NumberOfChecks() == 0) { |
| 373 // IC call for reoptimization populates original ICData. |
| 374 equality_ic_data = original_ic_data.raw(); |
| 375 } else { |
| 376 // Megamorphic call. |
| 377 equality_ic_data = original_ic_data.AsUnaryClassChecks(); |
| 378 } |
| 354 } else { | 379 } else { |
| 355 equality_ic_data = ICData::New(compiler->parsed_function().function(), | 380 equality_ic_data = ICData::New(compiler->parsed_function().function(), |
| 356 operator_name, | 381 operator_name, |
| 357 deopt_id, | 382 deopt_id, |
| 358 kNumArgumentsChecked); | 383 kNumArgumentsChecked); |
| 359 } | 384 } |
| 360 compiler->GenerateInstanceCall(deopt_id, | 385 compiler->GenerateInstanceCall(deopt_id, |
| 361 token_pos, | 386 token_pos, |
| 362 kNumberOfArguments, | 387 kNumberOfArguments, |
| 363 kNoArgumentNames, | 388 kNoArgumentNames, |
| (...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 if (!compiler->is_optimizing()) { | 988 if (!compiler->is_optimizing()) { |
| 964 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 989 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, |
| 965 deopt_id(), | 990 deopt_id(), |
| 966 token_pos()); | 991 token_pos()); |
| 967 } | 992 } |
| 968 const intptr_t kNumArguments = 2; | 993 const intptr_t kNumArguments = 2; |
| 969 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 994 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 970 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); | 995 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); |
| 971 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | 996 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
| 972 ASSERT(!ic_data()->IsNull()); | 997 ASSERT(!ic_data()->IsNull()); |
| 973 relational_ic_data = ic_data()->AsUnaryClassChecks(); | 998 if (ic_data()->NumberOfChecks() == 0) { |
| 999 // IC call for reoptimization populates original ICData. |
| 1000 relational_ic_data = ic_data()->raw(); |
| 1001 } else { |
| 1002 // Megamorphic call. |
| 1003 relational_ic_data = ic_data()->AsUnaryClassChecks(); |
| 1004 } |
| 974 } else { | 1005 } else { |
| 975 relational_ic_data = ICData::New(compiler->parsed_function().function(), | 1006 relational_ic_data = ICData::New(compiler->parsed_function().function(), |
| 976 function_name, | 1007 function_name, |
| 977 deopt_id(), | 1008 deopt_id(), |
| 978 kNumArgsChecked); | 1009 kNumArgsChecked); |
| 979 } | 1010 } |
| 980 compiler->GenerateInstanceCall(deopt_id(), | 1011 compiler->GenerateInstanceCall(deopt_id(), |
| 981 token_pos(), | 1012 token_pos(), |
| 982 kNumArguments, | 1013 kNumArguments, |
| 983 Array::ZoneHandle(), // No optional arguments. | 1014 Array::ZoneHandle(), // No optional arguments. |
| (...skipping 1707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2691 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 2722 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
| 2692 __ pxor(value, XMM0); | 2723 __ pxor(value, XMM0); |
| 2693 } | 2724 } |
| 2694 | 2725 |
| 2695 | 2726 |
| 2696 } // namespace dart | 2727 } // namespace dart |
| 2697 | 2728 |
| 2698 #undef __ | 2729 #undef __ |
| 2699 | 2730 |
| 2700 #endif // defined TARGET_ARCH_X64 | 2731 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |