Chromium Code Reviews| 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 25 matching lines...) Expand all Loading... | |
| 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 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 45 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 46 const Function& function = | |
| 47 Function::ZoneHandle(compiler->parsed_function().function().raw()); | |
| 46 Register result = locs()->in(0).reg(); | 48 Register result = locs()->in(0).reg(); |
| 47 Register func_reg = locs()->temp(0).reg(); | 49 Register func_reg = locs()->temp(0).reg(); |
| 48 ASSERT(result == EAX); | 50 ASSERT(result == EAX); |
| 49 if (!compiler->is_optimizing()) { | 51 if (compiler->is_optimizing()) { |
| 50 // Count only in unoptimized code. | 52 if (compiler->may_reoptimize()) { |
| 51 // TODO(srdjan): Replace the counting code with a type feedback | 53 // Increment of counter occurs only in optimized IC calls, as they |
| 52 // collection and counting stub. | 54 // can cause reoptimization. |
| 53 const Function& function = | 55 Label done; |
| 54 Function::ZoneHandle(compiler->parsed_function().function().raw()); | 56 __ LoadObject(func_reg, function); |
| 57 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), | |
| 58 Immediate(FLAG_optimization_counter_threshold)); | |
| 59 __ j(LESS, &done, Assembler::kNearJump); | |
| 60 // Equal (or greater), optimize. Note that counter can reach equality | |
| 61 // only at return instruction. | |
| 62 // The stub call preserves result register (EAX). | |
| 63 ASSERT(func_reg == EDX); | |
| 64 compiler->GenerateCall(0, // no token position. | |
|
Kevin Millikin (Google)
2012/11/13 17:56:53
I always have to figure out why we optimize at ret
srdjan
2012/11/13 18:21:39
Done:
// Attempt optimized compilation at return i
| |
| 65 &StubCode::OptimizeFunctionLabel(), | |
| 66 PcDescriptors::kOther, | |
| 67 locs()); | |
| 68 __ Bind(&done); | |
| 69 } | |
| 70 } else { | |
| 55 __ LoadObject(func_reg, function); | 71 __ LoadObject(func_reg, function); |
| 56 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | 72 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
| 57 if (FlowGraphCompiler::CanOptimize() && | 73 if (FlowGraphCompiler::CanOptimize() && |
| 58 compiler->parsed_function().function().is_optimizable()) { | 74 compiler->parsed_function().function().is_optimizable()) { |
| 59 // Do not optimize if usage count must be reported. | 75 // Do not optimize if usage count must be reported. |
| 60 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), | 76 __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), |
| 61 Immediate(FLAG_optimization_counter_threshold)); | 77 Immediate(FLAG_optimization_counter_threshold)); |
| 62 Label not_yet_hot; | 78 Label not_yet_hot; |
| 63 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); | 79 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); |
| 64 // Equal (or greater), optimize. | 80 // Equal (or greater), optimize. |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 355 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 340 Label check_identity; | 356 Label check_identity; |
| 341 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); | 357 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); |
| 342 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 358 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 343 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); | 359 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); |
| 344 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 360 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 345 | 361 |
| 346 ICData& equality_ic_data = ICData::ZoneHandle(); | 362 ICData& equality_ic_data = ICData::ZoneHandle(); |
| 347 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | 363 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
| 348 ASSERT(!original_ic_data.IsNull()); | 364 ASSERT(!original_ic_data.IsNull()); |
| 349 equality_ic_data = original_ic_data.AsUnaryClassChecks(); | 365 if (original_ic_data.NumberOfChecks() == 0) { |
| 366 // IC call for reoptimization populates original ICData. | |
| 367 equality_ic_data = original_ic_data.raw(); | |
| 368 } else { | |
| 369 // Megamorphic call. | |
| 370 equality_ic_data = original_ic_data.AsUnaryClassChecks(); | |
| 371 } | |
| 350 } else { | 372 } else { |
| 351 equality_ic_data = ICData::New(compiler->parsed_function().function(), | 373 equality_ic_data = ICData::New(compiler->parsed_function().function(), |
| 352 operator_name, | 374 operator_name, |
| 353 deopt_id, | 375 deopt_id, |
| 354 kNumArgumentsChecked); | 376 kNumArgumentsChecked); |
| 355 } | 377 } |
| 356 compiler->GenerateInstanceCall(deopt_id, | 378 compiler->GenerateInstanceCall(deopt_id, |
| 357 token_pos, | 379 token_pos, |
| 358 kNumberOfArguments, | 380 kNumberOfArguments, |
| 359 kNoArgumentNames, | 381 kNoArgumentNames, |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 981 if (!compiler->is_optimizing()) { | 1003 if (!compiler->is_optimizing()) { |
| 982 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 1004 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, |
| 983 deopt_id(), | 1005 deopt_id(), |
| 984 token_pos()); | 1006 token_pos()); |
| 985 } | 1007 } |
| 986 const intptr_t kNumArguments = 2; | 1008 const intptr_t kNumArguments = 2; |
| 987 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 1009 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 988 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); | 1010 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); |
| 989 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | 1011 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
| 990 ASSERT(!ic_data()->IsNull()); | 1012 ASSERT(!ic_data()->IsNull()); |
| 991 relational_ic_data = ic_data()->AsUnaryClassChecks(); | 1013 if (ic_data()->NumberOfChecks() == 0) { |
| 1014 // IC call for reoptimization populates original ICData. | |
| 1015 relational_ic_data = ic_data()->raw(); | |
| 1016 } else { | |
| 1017 // Megamorphic call. | |
| 1018 relational_ic_data = ic_data()->AsUnaryClassChecks(); | |
| 1019 } | |
| 992 } else { | 1020 } else { |
| 993 relational_ic_data = ICData::New(compiler->parsed_function().function(), | 1021 relational_ic_data = ICData::New(compiler->parsed_function().function(), |
| 994 function_name, | 1022 function_name, |
| 995 deopt_id(), | 1023 deopt_id(), |
| 996 kNumArgsChecked); | 1024 kNumArgsChecked); |
| 997 } | 1025 } |
| 998 compiler->GenerateInstanceCall(deopt_id(), | 1026 compiler->GenerateInstanceCall(deopt_id(), |
| 999 token_pos(), | 1027 token_pos(), |
| 1000 kNumArguments, | 1028 kNumArguments, |
| 1001 Array::ZoneHandle(), // No optional arguments. | 1029 Array::ZoneHandle(), // No optional arguments. |
| (...skipping 1707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2709 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 2737 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
| 2710 __ pxor(value, XMM0); | 2738 __ pxor(value, XMM0); |
| 2711 } | 2739 } |
| 2712 | 2740 |
| 2713 | 2741 |
| 2714 } // namespace dart | 2742 } // namespace dart |
| 2715 | 2743 |
| 2716 #undef __ | 2744 #undef __ |
| 2717 | 2745 |
| 2718 #endif // defined TARGET_ARCH_X64 | 2746 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |