| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 // this information to the input policy. | 962 // this information to the input policy. |
| 963 return LocationSummary::Make(1, | 963 return LocationSummary::Make(1, |
| 964 Location::RequiresRegister(), | 964 Location::RequiresRegister(), |
| 965 LocationSummary::kNoCall); | 965 LocationSummary::kNoCall); |
| 966 } | 966 } |
| 967 | 967 |
| 968 | 968 |
| 969 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 969 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 970 Register instance_reg = locs()->in(0).reg(); | 970 Register instance_reg = locs()->in(0).reg(); |
| 971 Register result_reg = locs()->out().reg(); | 971 Register result_reg = locs()->out().reg(); |
| 972 | |
| 973 if (HasICData()) { | |
| 974 ASSERT(original() != NULL); | |
| 975 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | |
| 976 original()->try_index(), | |
| 977 kDeoptInstanceGetterSameTarget); | |
| 978 // Smis do not have instance fields (Smi class is always first). | |
| 979 // Use 'result' as temporary register. | |
| 980 ASSERT(result_reg != instance_reg); | |
| 981 ASSERT(ic_data() != NULL); | |
| 982 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | |
| 983 } | |
| 984 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); | 972 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); |
| 985 } | 973 } |
| 986 | 974 |
| 987 | 975 |
| 988 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | 976 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
| 989 const intptr_t kNumInputs = 2; | 977 const intptr_t kNumInputs = 2; |
| 990 const intptr_t num_temps = HasICData() ? 1 : 0; | 978 const intptr_t num_temps = 0; |
| 991 LocationSummary* summary = | 979 LocationSummary* summary = |
| 992 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); | 980 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
| 993 summary->set_in(0, Location::RequiresRegister()); | 981 summary->set_in(0, Location::RequiresRegister()); |
| 994 summary->set_in(1, Location::RequiresRegister()); | 982 summary->set_in(1, Location::RequiresRegister()); |
| 995 if (HasICData()) { | |
| 996 summary->set_temp(0, Location::RequiresRegister()); | |
| 997 } | |
| 998 return summary; | 983 return summary; |
| 999 } | 984 } |
| 1000 | 985 |
| 1001 | 986 |
| 1002 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 987 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1003 Register instance_reg = locs()->in(0).reg(); | 988 Register instance_reg = locs()->in(0).reg(); |
| 1004 Register value_reg = locs()->in(1).reg(); | 989 Register value_reg = locs()->in(1).reg(); |
| 1005 | |
| 1006 if (HasICData()) { | |
| 1007 ASSERT(original() != NULL); | |
| 1008 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | |
| 1009 original()->try_index(), | |
| 1010 kDeoptInstanceGetterSameTarget); | |
| 1011 // Smis do not have instance fields (Smi class is always first). | |
| 1012 Register temp_reg = locs()->temp(0).reg(); | |
| 1013 ASSERT(temp_reg != instance_reg); | |
| 1014 ASSERT(temp_reg != value_reg); | |
| 1015 ASSERT(ic_data() != NULL); | |
| 1016 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); | |
| 1017 } | |
| 1018 if (this->value()->NeedsStoreBuffer()) { | 990 if (this->value()->NeedsStoreBuffer()) { |
| 1019 __ StoreIntoObject(instance_reg, | 991 __ StoreIntoObject(instance_reg, |
| 1020 FieldAddress(instance_reg, field().Offset()), value_reg); | 992 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1021 } else { | 993 } else { |
| 1022 __ StoreIntoObjectNoBarrier(instance_reg, | 994 __ StoreIntoObjectNoBarrier(instance_reg, |
| 1023 FieldAddress(instance_reg, field().Offset()), value_reg); | 995 FieldAddress(instance_reg, field().Offset()), value_reg); |
| 1024 } | 996 } |
| 1025 } | 997 } |
| 1026 | 998 |
| 1027 | 999 |
| (...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2367 return locs; | 2339 return locs; |
| 2368 } | 2340 } |
| 2369 | 2341 |
| 2370 | 2342 |
| 2371 void StrictCompareAndBranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2343 void StrictCompareAndBranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2372 Register left = locs()->in(0).reg(); | 2344 Register left = locs()->in(0).reg(); |
| 2373 Register right = locs()->in(1).reg(); | 2345 Register right = locs()->in(1).reg(); |
| 2374 __ cmpq(left, right); | 2346 __ cmpq(left, right); |
| 2375 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 2347 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 2376 EmitBranchOnCondition(compiler, cond); | 2348 EmitBranchOnCondition(compiler, cond); |
| 2377 return; | |
| 2378 } | 2349 } |
| 2379 | 2350 |
| 2380 | 2351 |
| 2381 LocationSummary* CheckClassComp::MakeLocationSummary() const { | 2352 LocationSummary* CheckClassComp::MakeLocationSummary() const { |
| 2382 const intptr_t kNumInputs = 1; | 2353 const intptr_t kNumInputs = 1; |
| 2383 const intptr_t kNumTemps = 1; | 2354 const intptr_t kNumTemps = 1; |
| 2384 LocationSummary* summary = | 2355 LocationSummary* summary = |
| 2385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2386 summary->set_in(0, Location::RequiresRegister()); | 2357 summary->set_in(0, Location::RequiresRegister()); |
| 2387 summary->set_temp(0, Location::RequiresRegister()); | 2358 summary->set_temp(0, Location::RequiresRegister()); |
| 2388 return summary; | 2359 return summary; |
| 2389 } | 2360 } |
| 2390 | 2361 |
| 2391 | 2362 |
| 2392 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2363 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2393 const intptr_t v_cid = value()->ResultCid(); | |
| 2394 const intptr_t num_checks = ic_data()->NumberOfChecks(); | |
| 2395 if ((num_checks == 1) && | |
| 2396 (v_cid == ic_data()->GetReceiverClassIdAt(0))) { | |
| 2397 // No checks needed. | |
| 2398 // TODO(srdjan): Should the computation have been removed instead? | |
| 2399 return; | |
| 2400 } | |
| 2401 Register value = locs()->in(0).reg(); | 2364 Register value = locs()->in(0).reg(); |
| 2402 Register temp = locs()->temp(0).reg(); | 2365 Register temp = locs()->temp(0).reg(); |
| 2403 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2366 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2404 try_index(), | 2367 try_index(), |
| 2405 kDeoptCheckClass); | 2368 kDeoptCheckClass); |
| 2406 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); | 2369 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); |
| 2407 __ testq(value, Immediate(kSmiTagMask)); | 2370 __ testq(value, Immediate(kSmiTagMask)); |
| 2408 __ j(ZERO, deopt); | 2371 __ j(ZERO, deopt); |
| 2409 __ LoadClassId(temp, value); | 2372 __ LoadClassId(temp, value); |
| 2410 Label is_ok; | 2373 Label is_ok; |
| 2374 const intptr_t num_checks = ic_data()->NumberOfChecks(); |
| 2411 const bool use_near_jump = num_checks < 5; | 2375 const bool use_near_jump = num_checks < 5; |
| 2412 for (intptr_t i = 0; i < num_checks; i++) { | 2376 for (intptr_t i = 0; i < num_checks; i++) { |
| 2413 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); | 2377 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); |
| 2414 if (i == (num_checks - 1)) { | 2378 if (i == (num_checks - 1)) { |
| 2415 __ j(NOT_EQUAL, deopt); | 2379 __ j(NOT_EQUAL, deopt); |
| 2416 } else { | 2380 } else { |
| 2417 if (use_near_jump) { | 2381 if (use_near_jump) { |
| 2418 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 2382 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 2419 } else { | 2383 } else { |
| 2420 __ j(EQUAL, &is_ok); | 2384 __ j(EQUAL, &is_ok); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2443 __ testq(value, Immediate(kSmiTagMask)); | 2407 __ testq(value, Immediate(kSmiTagMask)); |
| 2444 __ j(NOT_ZERO, deopt); | 2408 __ j(NOT_ZERO, deopt); |
| 2445 } | 2409 } |
| 2446 | 2410 |
| 2447 | 2411 |
| 2448 } // namespace dart | 2412 } // namespace dart |
| 2449 | 2413 |
| 2450 #undef __ | 2414 #undef __ |
| 2451 | 2415 |
| 2452 #endif // defined TARGET_ARCH_X64 | 2416 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |