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 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 939 // TODO(fschneider): For this instruction the input register may be | 939 // TODO(fschneider): For this instruction the input register may be |
| 940 // reused for the result (but is not required to) because the input | 940 // reused for the result (but is not required to) because the input |
| 941 // is not used after the result is defined. We should consider adding | 941 // is not used after the result is defined. We should consider adding |
| 942 // this information to the input policy. | 942 // this information to the input policy. |
| 943 return LocationSummary::Make(1, | 943 return LocationSummary::Make(1, |
| 944 Location::RequiresRegister(), | 944 Location::RequiresRegister(), |
| 945 LocationSummary::kNoCall); | 945 LocationSummary::kNoCall); |
| 946 } | 946 } |
| 947 | 947 |
| 948 | 948 |
| 949 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 949 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
|
Vyacheslav Egorov (Google)
2012/08/27 13:37:50
I think Load|StoreInstanceFieldComp and Load|Store
| |
| 950 Register instance_reg = locs()->in(0).reg(); | 950 Register instance_reg = locs()->in(0).reg(); |
| 951 Register result_reg = locs()->out().reg(); | 951 Register result_reg = locs()->out().reg(); |
| 952 | |
| 953 if (HasICData()) { | |
| 954 ASSERT(original() != NULL); | |
| 955 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | |
| 956 original()->try_index(), | |
| 957 kDeoptInstanceGetterSameTarget); | |
| 958 // Smis do not have instance fields (Smi class is always first). | |
| 959 // Use 'result' as temporary register. | |
| 960 ASSERT(result_reg != instance_reg); | |
| 961 ASSERT(ic_data() != NULL); | |
| 962 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | |
| 963 } | |
| 964 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); | 952 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); |
| 965 } | 953 } |
| 966 | 954 |
| 967 | 955 |
| 968 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | 956 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
| 969 const intptr_t kNumInputs = 2; | 957 const intptr_t kNumInputs = 2; |
| 970 const intptr_t num_temps = HasICData() ? 1 : 0; | 958 const intptr_t num_temps = 0; |
| 971 LocationSummary* summary = | 959 LocationSummary* summary = |
| 972 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); | 960 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
| 973 summary->set_in(0, Location::RequiresRegister()); | 961 summary->set_in(0, Location::RequiresRegister()); |
| 974 summary->set_in(1, Location::RequiresRegister()); | 962 summary->set_in(1, Location::RequiresRegister()); |
| 975 if (HasICData()) { | |
| 976 summary->set_temp(0, Location::RequiresRegister()); | |
| 977 } | |
| 978 return summary; | 963 return summary; |
| 979 } | 964 } |
| 980 | 965 |
| 981 | 966 |
| 982 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 967 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 983 Register instance_reg = locs()->in(0).reg(); | 968 Register instance_reg = locs()->in(0).reg(); |
| 984 Register value_reg = locs()->in(1).reg(); | 969 Register value_reg = locs()->in(1).reg(); |
| 985 | |
| 986 if (HasICData()) { | |
| 987 ASSERT(original() != NULL); | |
| 988 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | |
| 989 original()->try_index(), | |
| 990 kDeoptInstanceGetterSameTarget); | |
| 991 // Smis do not have instance fields (Smi class is always first). | |
| 992 Register temp_reg = locs()->temp(0).reg(); | |
| 993 ASSERT(temp_reg != instance_reg); | |
| 994 ASSERT(temp_reg != value_reg); | |
| 995 ASSERT(ic_data() != NULL); | |
| 996 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); | |
| 997 } | |
| 998 if (this->value()->NeedsStoreBuffer()) { | 970 if (this->value()->NeedsStoreBuffer()) { |
| 999 __ StoreIntoObject(instance_reg, | 971 __ StoreIntoObject(instance_reg, |
| 1000 FieldAddress(instance_reg, field().Offset()), value_reg); | 972 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1001 } else { | 973 } else { |
| 1002 __ StoreIntoObjectNoBarrier(instance_reg, | 974 __ StoreIntoObjectNoBarrier(instance_reg, |
| 1003 FieldAddress(instance_reg, field().Offset()), value_reg); | 975 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1004 } | 976 } |
| 1005 } | 977 } |
| 1006 | 978 |
| 1007 | 979 |
| (...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2355 return locs; | 2327 return locs; |
| 2356 } | 2328 } |
| 2357 | 2329 |
| 2358 | 2330 |
| 2359 void StrictCompareAndBranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2331 void StrictCompareAndBranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2360 Register left = locs()->in(0).reg(); | 2332 Register left = locs()->in(0).reg(); |
| 2361 Register right = locs()->in(1).reg(); | 2333 Register right = locs()->in(1).reg(); |
| 2362 __ cmpl(left, right); | 2334 __ cmpl(left, right); |
| 2363 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 2335 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 2364 EmitBranchOnCondition(compiler, cond); | 2336 EmitBranchOnCondition(compiler, cond); |
| 2365 return; | |
| 2366 } | 2337 } |
| 2367 | 2338 |
| 2368 | 2339 |
| 2369 LocationSummary* CheckClassComp::MakeLocationSummary() const { | 2340 LocationSummary* CheckClassComp::MakeLocationSummary() const { |
| 2370 const intptr_t kNumInputs = 1; | 2341 const intptr_t kNumInputs = 1; |
| 2371 const intptr_t kNumTemps = 1; | 2342 const intptr_t kNumTemps = 1; |
| 2372 LocationSummary* summary = | 2343 LocationSummary* summary = |
| 2373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2374 summary->set_in(0, Location::RequiresRegister()); | 2345 summary->set_in(0, Location::RequiresRegister()); |
| 2375 summary->set_temp(0, Location::RequiresRegister()); | 2346 summary->set_temp(0, Location::RequiresRegister()); |
| 2376 return summary; | 2347 return summary; |
| 2377 } | 2348 } |
| 2378 | 2349 |
| 2379 | 2350 |
| 2380 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2351 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2381 const intptr_t v_cid = value()->ResultCid(); | |
| 2382 const intptr_t num_checks = ic_data()->NumberOfChecks(); | |
| 2383 if ((num_checks == 1) && | |
| 2384 (v_cid == ic_data()->GetReceiverClassIdAt(0))) { | |
| 2385 // No checks needed. | |
| 2386 // TODO(srdjan): Should the computation have been removed instead? | |
| 2387 return; | |
| 2388 } | |
| 2389 Register value = locs()->in(0).reg(); | 2352 Register value = locs()->in(0).reg(); |
| 2390 Register temp = locs()->temp(0).reg(); | 2353 Register temp = locs()->temp(0).reg(); |
| 2391 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2354 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2392 try_index(), | 2355 try_index(), |
| 2393 kDeoptCheckClass); | 2356 kDeoptCheckClass); |
| 2394 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); | 2357 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); |
| 2395 __ testl(value, Immediate(kSmiTagMask)); | 2358 __ testl(value, Immediate(kSmiTagMask)); |
| 2396 __ j(ZERO, deopt); | 2359 __ j(ZERO, deopt); |
| 2397 __ LoadClassId(temp, value); | 2360 __ LoadClassId(temp, value); |
| 2398 Label is_ok; | 2361 Label is_ok; |
| 2362 const intptr_t num_checks = ic_data()->NumberOfChecks(); | |
| 2399 const bool use_near_jump = num_checks < 5; | 2363 const bool use_near_jump = num_checks < 5; |
| 2400 for (intptr_t i = 0; i < num_checks; i++) { | 2364 for (intptr_t i = 0; i < num_checks; i++) { |
| 2401 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); | 2365 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); |
| 2402 if (i == (num_checks - 1)) { | 2366 if (i == (num_checks - 1)) { |
| 2403 __ j(NOT_EQUAL, deopt); | 2367 __ j(NOT_EQUAL, deopt); |
| 2404 } else { | 2368 } else { |
| 2405 if (use_near_jump) { | 2369 if (use_near_jump) { |
| 2406 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 2370 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 2407 } else { | 2371 } else { |
| 2408 __ j(EQUAL, &is_ok); | 2372 __ j(EQUAL, &is_ok); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2431 __ testl(value, Immediate(kSmiTagMask)); | 2395 __ testl(value, Immediate(kSmiTagMask)); |
| 2432 __ j(NOT_ZERO, deopt); | 2396 __ j(NOT_ZERO, deopt); |
| 2433 } | 2397 } |
| 2434 | 2398 |
| 2435 | 2399 |
| 2436 } // namespace dart | 2400 } // namespace dart |
| 2437 | 2401 |
| 2438 #undef __ | 2402 #undef __ |
| 2439 | 2403 |
| 2440 #endif // defined TARGET_ARCH_X64 | 2404 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |