| 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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 try_index(), | 417 try_index(), |
| 418 function_name, | 418 function_name, |
| 419 kNumArguments, | 419 kNumArguments, |
| 420 Array::ZoneHandle(), // No optional arguments. | 420 Array::ZoneHandle(), // No optional arguments. |
| 421 kNumArgsChecked); | 421 kNumArgsChecked); |
| 422 } | 422 } |
| 423 | 423 |
| 424 | 424 |
| 425 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 425 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
| 426 const intptr_t kNumInputs = 3; | 426 const intptr_t kNumInputs = 3; |
| 427 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 427 if (receiver_type() == kGrowableObjectArray || receiver_type() == kArray) { |
| 428 const intptr_t kNumTemps = 1; |
| 429 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 430 locs->set_in(0, Location::RequiresRegister()); |
| 431 locs->set_in(1, Location::RequiresRegister()); |
| 432 locs->set_in(2, Location::RequiresRegister()); |
| 433 locs->set_temp(0, Location::RequiresRegister()); |
| 434 locs->set_out(Location::NoLocation()); |
| 435 return locs; |
| 436 } else { |
| 437 ASSERT(receiver_type() == kIllegalObjectKind); |
| 438 return MakeCallSummary(); |
| 439 } |
| 428 } | 440 } |
| 429 | 441 |
| 430 | 442 |
| 431 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 432 Register receiver = locs()->in(0).reg(); | |
| 433 Register index = locs()->in(1).reg(); | |
| 434 Register value = locs()->in(2).reg(); | |
| 435 | 443 |
| 444 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, |
| 445 StoreIndexedComp* comp) { |
| 436 const String& function_name = | 446 const String& function_name = |
| 437 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 447 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 438 | 448 |
| 439 __ pushl(receiver); | 449 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 440 __ pushl(index); | 450 comp->cid(), |
| 441 __ pushl(value); | 451 comp->token_index(), |
| 452 comp->try_index()); |
| 453 |
| 442 const intptr_t kNumArguments = 3; | 454 const intptr_t kNumArguments = 3; |
| 443 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 455 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
| 444 compiler->GenerateInstanceCall(cid(), | 456 compiler->GenerateInstanceCall(comp->cid(), |
| 445 token_index(), | 457 comp->token_index(), |
| 446 try_index(), | 458 comp->try_index(), |
| 447 function_name, | 459 function_name, |
| 448 kNumArguments, | 460 kNumArguments, |
| 449 Array::ZoneHandle(), // No optional arguments. | 461 Array::ZoneHandle(), // No optional arguments. |
| 450 kNumArgsChecked); | 462 kNumArgsChecked); |
| 451 } | 463 } |
| 452 | 464 |
| 453 | 465 |
| 466 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 467 if (receiver_type() == kIllegalObjectKind) { |
| 468 EmitStoreIndexedGeneric(compiler, this); |
| 469 return; |
| 470 } |
| 471 |
| 472 Register receiver = locs()->in(0).reg(); |
| 473 Register index = locs()->in(1).reg(); |
| 474 Register value = locs()->in(2).reg(); |
| 475 Register temp = locs()->temp(0).reg(); |
| 476 |
| 477 Label* deopt = compiler->AddDeoptStub(cid(), |
| 478 token_index(), |
| 479 try_index(), |
| 480 kDeoptStoreIndexed, |
| 481 receiver, |
| 482 index, |
| 483 value); |
| 484 |
| 485 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 486 __ j(ZERO, deopt); |
| 487 __ CompareClassId(receiver, receiver_type(), temp); |
| 488 __ j(NOT_EQUAL, deopt); |
| 489 |
| 490 __ testl(index, Immediate(kSmiTagMask)); |
| 491 __ j(NOT_ZERO, deopt); |
| 492 |
| 493 switch (receiver_type()) { |
| 494 case kArray: |
| 495 case kImmutableArray: |
| 496 __ cmpl(index, FieldAddress(receiver, Array::length_offset())); |
| 497 __ j(ABOVE_EQUAL, deopt); |
| 498 // Note that index is Smi, i.e, times 2. |
| 499 ASSERT(kSmiTagShift == 1); |
| 500 __ StoreIntoObject(receiver, |
| 501 FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)), |
| 502 value); |
| 503 break; |
| 504 |
| 505 case kGrowableObjectArray: { |
| 506 __ cmpl(index, |
| 507 FieldAddress(receiver, GrowableObjectArray::length_offset())); |
| 508 __ j(ABOVE_EQUAL, deopt); |
| 509 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); |
| 510 // Note that index is Smi, i.e, times 2. |
| 511 ASSERT(kSmiTagShift == 1); |
| 512 __ StoreIntoObject(temp, |
| 513 FieldAddress(temp, index, TIMES_2, sizeof(RawArray)), |
| 514 value); |
| 515 break; |
| 516 } |
| 517 |
| 518 default: |
| 519 UNREACHABLE(); |
| 520 break; |
| 521 } |
| 522 } |
| 523 |
| 524 |
| 454 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 525 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
| 455 const intptr_t kNumInputs = 2; | 526 const intptr_t kNumInputs = 2; |
| 456 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 527 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
| 457 } | 528 } |
| 458 | 529 |
| 459 | 530 |
| 460 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 531 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 461 Register receiver = locs()->in(0).reg(); | 532 Register receiver = locs()->in(0).reg(); |
| 462 Register value = locs()->in(1).reg(); | 533 Register value = locs()->in(1).reg(); |
| 463 | 534 |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 UNREACHABLE(); | 1318 UNREACHABLE(); |
| 1248 } | 1319 } |
| 1249 } | 1320 } |
| 1250 | 1321 |
| 1251 | 1322 |
| 1252 } // namespace dart | 1323 } // namespace dart |
| 1253 | 1324 |
| 1254 #undef __ | 1325 #undef __ |
| 1255 | 1326 |
| 1256 #endif // defined TARGET_ARCH_X64 | 1327 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |