OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // Get the global function with the given index. | 300 // Get the global function with the given index. |
301 Handle<JSFunction> function( | 301 Handle<JSFunction> function( |
302 JSFunction::cast(isolate->native_context()->get(index))); | 302 JSFunction::cast(isolate->native_context()->get(index))); |
303 // Load its initial map. The global functions all have initial maps. | 303 // Load its initial map. The global functions all have initial maps. |
304 __ li(prototype, Handle<Map>(function->initial_map())); | 304 __ li(prototype, Handle<Map>(function->initial_map())); |
305 // Load the prototype from the initial map. | 305 // Load the prototype from the initial map. |
306 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 306 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
307 } | 307 } |
308 | 308 |
309 | 309 |
310 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm, | 310 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
311 Register dst, | 311 Register dst, |
312 Register src, | 312 Register src, |
313 bool inobject, | 313 bool inobject, |
314 int index) { | 314 int index, |
| 315 Representation representation) { |
| 316 ASSERT(!FLAG_track_double_fields || !representation.IsDouble()); |
315 int offset = index * kPointerSize; | 317 int offset = index * kPointerSize; |
316 if (!inobject) { | 318 if (!inobject) { |
317 // Calculate the offset into the properties array. | 319 // Calculate the offset into the properties array. |
318 offset = offset + FixedArray::kHeaderSize; | 320 offset = offset + FixedArray::kHeaderSize; |
319 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 321 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |
320 src = dst; | 322 src = dst; |
321 } | 323 } |
322 __ lw(dst, FieldMemOperand(src, offset)); | 324 __ lw(dst, FieldMemOperand(src, offset)); |
323 } | 325 } |
324 | 326 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 437 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
436 Handle<JSObject> object, | 438 Handle<JSObject> object, |
437 LookupResult* lookup, | 439 LookupResult* lookup, |
438 Handle<Map> transition, | 440 Handle<Map> transition, |
439 Handle<Name> name, | 441 Handle<Name> name, |
440 Register receiver_reg, | 442 Register receiver_reg, |
441 Register name_reg, | 443 Register name_reg, |
442 Register value_reg, | 444 Register value_reg, |
443 Register scratch1, | 445 Register scratch1, |
444 Register scratch2, | 446 Register scratch2, |
| 447 Register scratch3, |
445 Label* miss_label, | 448 Label* miss_label, |
446 Label* miss_restore_name) { | 449 Label* miss_restore_name, |
| 450 Label* slow) { |
447 // a0 : value. | 451 // a0 : value. |
448 Label exit; | 452 Label exit; |
449 | 453 |
450 // Check that the map of the object hasn't changed. | 454 // Check that the map of the object hasn't changed. |
451 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, | 455 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, |
452 DO_SMI_CHECK, REQUIRE_EXACT_MAP); | 456 DO_SMI_CHECK, REQUIRE_EXACT_MAP); |
453 | 457 |
454 // Perform global security token check if needed. | 458 // Perform global security token check if needed. |
455 if (object->IsJSGlobalProxy()) { | 459 if (object->IsJSGlobalProxy()) { |
456 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); | 460 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); |
457 } | 461 } |
458 | 462 |
459 int descriptor = transition->LastAdded(); | 463 int descriptor = transition->LastAdded(); |
460 DescriptorArray* descriptors = transition->instance_descriptors(); | 464 DescriptorArray* descriptors = transition->instance_descriptors(); |
461 PropertyDetails details = descriptors->GetDetails(descriptor); | 465 PropertyDetails details = descriptors->GetDetails(descriptor); |
462 Representation representation = details.representation(); | 466 Representation representation = details.representation(); |
463 ASSERT(!representation.IsNone()); | 467 ASSERT(!representation.IsNone()); |
464 | 468 |
465 // Ensure no transitions to deprecated maps are followed. | 469 // Ensure no transitions to deprecated maps are followed. |
466 __ CheckMapDeprecated(transition, scratch1, miss_label); | 470 __ CheckMapDeprecated(transition, scratch1, miss_label); |
467 | 471 |
468 if (FLAG_track_fields && representation.IsSmi()) { | |
469 __ JumpIfNotSmi(value_reg, miss_label); | |
470 } else if (FLAG_track_double_fields && representation.IsDouble()) { | |
471 Label do_store; | |
472 __ JumpIfSmi(value_reg, &do_store); | |
473 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | |
474 miss_label, DONT_DO_SMI_CHECK); | |
475 __ bind(&do_store); | |
476 } | |
477 | |
478 // Check that we are allowed to write this. | 472 // Check that we are allowed to write this. |
479 if (object->GetPrototype()->IsJSObject()) { | 473 if (object->GetPrototype()->IsJSObject()) { |
480 JSObject* holder; | 474 JSObject* holder; |
481 // holder == object indicates that no property was found. | 475 // holder == object indicates that no property was found. |
482 if (lookup->holder() != *object) { | 476 if (lookup->holder() != *object) { |
483 holder = lookup->holder(); | 477 holder = lookup->holder(); |
484 } else { | 478 } else { |
485 // Find the top object. | 479 // Find the top object. |
486 holder = *object; | 480 holder = *object; |
487 do { | 481 do { |
488 holder = JSObject::cast(holder->GetPrototype()); | 482 holder = JSObject::cast(holder->GetPrototype()); |
489 } while (holder->GetPrototype()->IsJSObject()); | 483 } while (holder->GetPrototype()->IsJSObject()); |
490 } | 484 } |
491 Register holder_reg = CheckPrototypes( | 485 Register holder_reg = CheckPrototypes( |
492 object, receiver_reg, Handle<JSObject>(holder), name_reg, | 486 object, receiver_reg, Handle<JSObject>(holder), name_reg, |
493 scratch1, scratch2, name, miss_restore_name); | 487 scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER); |
494 // If no property was found, and the holder (the last object in the | 488 // If no property was found, and the holder (the last object in the |
495 // prototype chain) is in slow mode, we need to do a negative lookup on the | 489 // prototype chain) is in slow mode, we need to do a negative lookup on the |
496 // holder. | 490 // holder. |
497 if (lookup->holder() == *object) { | 491 if (lookup->holder() == *object) { |
498 if (holder->IsJSGlobalObject()) { | 492 if (holder->IsJSGlobalObject()) { |
499 GenerateCheckPropertyCell( | 493 GenerateCheckPropertyCell( |
500 masm, | 494 masm, |
501 Handle<GlobalObject>(GlobalObject::cast(holder)), | 495 Handle<GlobalObject>(GlobalObject::cast(holder)), |
502 name, | 496 name, |
503 scratch1, | 497 scratch1, |
504 miss_restore_name); | 498 miss_restore_name); |
505 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 499 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
506 GenerateDictionaryNegativeLookup( | 500 GenerateDictionaryNegativeLookup( |
507 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); | 501 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
508 } | 502 } |
509 } | 503 } |
510 } | 504 } |
511 | 505 |
| 506 Register storage_reg = name_reg; |
| 507 |
| 508 if (FLAG_track_fields && representation.IsSmi()) { |
| 509 __ JumpIfNotSmi(value_reg, miss_restore_name); |
| 510 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 511 Label do_store, heap_number; |
| 512 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); |
| 513 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); |
| 514 |
| 515 __ JumpIfNotSmi(value_reg, &heap_number); |
| 516 __ SmiUntag(scratch1, value_reg); |
| 517 __ mtc1(scratch1, f6); |
| 518 __ cvt_d_w(f4, f6); |
| 519 __ jmp(&do_store); |
| 520 |
| 521 __ bind(&heap_number); |
| 522 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, |
| 523 miss_restore_name, DONT_DO_SMI_CHECK); |
| 524 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
| 525 |
| 526 __ bind(&do_store); |
| 527 __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); |
| 528 } |
| 529 |
512 // Stub never generated for non-global objects that require access | 530 // Stub never generated for non-global objects that require access |
513 // checks. | 531 // checks. |
514 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 532 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
515 | 533 |
516 // Perform map transition for the receiver if necessary. | 534 // Perform map transition for the receiver if necessary. |
517 if (object->map()->unused_property_fields() == 0) { | 535 if (object->map()->unused_property_fields() == 0) { |
518 // The properties must be extended before we can store the value. | 536 // The properties must be extended before we can store the value. |
519 // We jump to a runtime call that extends the properties array. | 537 // We jump to a runtime call that extends the properties array. |
520 __ push(receiver_reg); | 538 __ push(receiver_reg); |
521 __ li(a2, Operand(transition)); | 539 __ li(a2, Operand(transition)); |
522 __ Push(a2, a0); | 540 __ Push(a2, a0); |
523 __ TailCallExternalReference( | 541 __ TailCallExternalReference( |
524 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 542 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
525 masm->isolate()), | 543 masm->isolate()), |
526 3, 1); | 544 3, 1); |
527 return; | 545 return; |
528 } | 546 } |
529 | 547 |
530 // Update the map of the object. | 548 // Update the map of the object. |
531 __ li(scratch1, Operand(transition)); | 549 __ li(scratch1, Operand(transition)); |
532 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 550 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
533 | 551 |
534 // Update the write barrier for the map field and pass the now unused | 552 // Update the write barrier for the map field and pass the now unused |
535 // name_reg as scratch register. | 553 // name_reg as scratch register. |
536 __ RecordWriteField(receiver_reg, | 554 __ RecordWriteField(receiver_reg, |
537 HeapObject::kMapOffset, | 555 HeapObject::kMapOffset, |
538 scratch1, | 556 scratch1, |
539 name_reg, | 557 scratch2, |
540 kRAHasNotBeenSaved, | 558 kRAHasNotBeenSaved, |
541 kDontSaveFPRegs, | 559 kDontSaveFPRegs, |
542 OMIT_REMEMBERED_SET, | 560 OMIT_REMEMBERED_SET, |
543 OMIT_SMI_CHECK); | 561 OMIT_SMI_CHECK); |
544 | 562 |
545 int index = transition->instance_descriptors()->GetFieldIndex( | 563 int index = transition->instance_descriptors()->GetFieldIndex( |
546 transition->LastAdded()); | 564 transition->LastAdded()); |
547 | 565 |
548 // Adjust for the number of properties stored in the object. Even in the | 566 // Adjust for the number of properties stored in the object. Even in the |
549 // face of a transition we can use the old map here because the size of the | 567 // face of a transition we can use the old map here because the size of the |
550 // object and the number of in-object properties is not going to change. | 568 // object and the number of in-object properties is not going to change. |
551 index -= object->map()->inobject_properties(); | 569 index -= object->map()->inobject_properties(); |
552 | 570 |
553 // TODO(verwaest): Share this code as a code stub. | 571 // TODO(verwaest): Share this code as a code stub. |
554 if (index < 0) { | 572 if (index < 0) { |
555 // Set the property straight into the object. | 573 // Set the property straight into the object. |
556 int offset = object->map()->instance_size() + (index * kPointerSize); | 574 int offset = object->map()->instance_size() + (index * kPointerSize); |
557 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); | 575 if (FLAG_track_double_fields && representation.IsDouble()) { |
| 576 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset)); |
| 577 } else { |
| 578 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); |
| 579 } |
558 | 580 |
559 if (!FLAG_track_fields || !representation.IsSmi()) { | 581 if (!FLAG_track_fields || !representation.IsSmi()) { |
560 // Skip updating write barrier if storing a smi. | 582 // Skip updating write barrier if storing a smi. |
561 __ JumpIfSmi(value_reg, &exit); | 583 __ JumpIfSmi(value_reg, &exit); |
562 | 584 |
563 // Update the write barrier for the array address. | 585 // Update the write barrier for the array address. |
564 // Pass the now unused name_reg as a scratch register. | 586 // Pass the now unused name_reg as a scratch register. |
565 __ mov(name_reg, value_reg); | 587 if (!FLAG_track_double_fields || !representation.IsDouble()) { |
| 588 __ mov(name_reg, value_reg); |
| 589 } else { |
| 590 ASSERT(storage_reg.is(name_reg)); |
| 591 } |
566 __ RecordWriteField(receiver_reg, | 592 __ RecordWriteField(receiver_reg, |
567 offset, | 593 offset, |
568 name_reg, | 594 name_reg, |
569 scratch1, | 595 scratch1, |
570 kRAHasNotBeenSaved, | 596 kRAHasNotBeenSaved, |
571 kDontSaveFPRegs); | 597 kDontSaveFPRegs); |
572 } | 598 } |
573 } else { | 599 } else { |
574 // Write to the properties array. | 600 // Write to the properties array. |
575 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 601 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
576 // Get the properties array | 602 // Get the properties array |
577 __ lw(scratch1, | 603 __ lw(scratch1, |
578 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); | 604 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); |
579 __ sw(value_reg, FieldMemOperand(scratch1, offset)); | 605 if (FLAG_track_double_fields && representation.IsDouble()) { |
| 606 __ sw(storage_reg, FieldMemOperand(scratch1, offset)); |
| 607 } else { |
| 608 __ sw(value_reg, FieldMemOperand(scratch1, offset)); |
| 609 } |
580 | 610 |
581 if (!FLAG_track_fields || !representation.IsSmi()) { | 611 if (!FLAG_track_fields || !representation.IsSmi()) { |
582 // Skip updating write barrier if storing a smi. | 612 // Skip updating write barrier if storing a smi. |
583 __ JumpIfSmi(value_reg, &exit); | 613 __ JumpIfSmi(value_reg, &exit); |
584 | 614 |
585 // Update the write barrier for the array address. | 615 // Update the write barrier for the array address. |
586 // Ok to clobber receiver_reg and name_reg, since we return. | 616 // Ok to clobber receiver_reg and name_reg, since we return. |
| 617 if (!FLAG_track_double_fields || !representation.IsDouble()) { |
| 618 __ mov(name_reg, value_reg); |
| 619 } else { |
| 620 ASSERT(storage_reg.is(name_reg)); |
| 621 } |
587 __ mov(name_reg, value_reg); | 622 __ mov(name_reg, value_reg); |
588 __ RecordWriteField(scratch1, | 623 __ RecordWriteField(scratch1, |
589 offset, | 624 offset, |
590 name_reg, | 625 name_reg, |
591 receiver_reg, | 626 receiver_reg, |
592 kRAHasNotBeenSaved, | 627 kRAHasNotBeenSaved, |
593 kDontSaveFPRegs); | 628 kDontSaveFPRegs); |
594 } | 629 } |
595 } | 630 } |
596 | 631 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 // Adjust for the number of properties stored in the object. Even in the | 671 // Adjust for the number of properties stored in the object. Even in the |
637 // face of a transition we can use the old map here because the size of the | 672 // face of a transition we can use the old map here because the size of the |
638 // object and the number of in-object properties is not going to change. | 673 // object and the number of in-object properties is not going to change. |
639 index -= object->map()->inobject_properties(); | 674 index -= object->map()->inobject_properties(); |
640 | 675 |
641 Representation representation = lookup->representation(); | 676 Representation representation = lookup->representation(); |
642 ASSERT(!representation.IsNone()); | 677 ASSERT(!representation.IsNone()); |
643 if (FLAG_track_fields && representation.IsSmi()) { | 678 if (FLAG_track_fields && representation.IsSmi()) { |
644 __ JumpIfNotSmi(value_reg, miss_label); | 679 __ JumpIfNotSmi(value_reg, miss_label); |
645 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 680 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
646 Label do_store; | 681 // Load the double storage. |
647 __ JumpIfSmi(value_reg, &do_store); | 682 if (index < 0) { |
648 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | 683 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 684 __ lw(scratch1, FieldMemOperand(receiver_reg, offset)); |
| 685 } else { |
| 686 __ lw(scratch1, |
| 687 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 688 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 689 __ lw(scratch1, FieldMemOperand(scratch1, offset)); |
| 690 } |
| 691 |
| 692 // Store the value into the storage. |
| 693 Label do_store, heap_number; |
| 694 __ JumpIfNotSmi(value_reg, &heap_number); |
| 695 __ SmiUntag(scratch2, value_reg); |
| 696 __ mtc1(scratch2, f6); |
| 697 __ cvt_d_w(f4, f6); |
| 698 __ jmp(&do_store); |
| 699 |
| 700 __ bind(&heap_number); |
| 701 __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, |
649 miss_label, DONT_DO_SMI_CHECK); | 702 miss_label, DONT_DO_SMI_CHECK); |
| 703 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
| 704 |
650 __ bind(&do_store); | 705 __ bind(&do_store); |
| 706 __ sdc1(f4, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); |
| 707 // Return the value (register v0). |
| 708 ASSERT(value_reg.is(a0)); |
| 709 __ mov(v0, a0); |
| 710 __ Ret(); |
| 711 return; |
651 } | 712 } |
652 | 713 |
653 // TODO(verwaest): Share this code as a code stub. | 714 // TODO(verwaest): Share this code as a code stub. |
654 if (index < 0) { | 715 if (index < 0) { |
655 // Set the property straight into the object. | 716 // Set the property straight into the object. |
656 int offset = object->map()->instance_size() + (index * kPointerSize); | 717 int offset = object->map()->instance_size() + (index * kPointerSize); |
657 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); | 718 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); |
658 | 719 |
659 if (!FLAG_track_fields || !representation.IsSmi()) { | 720 if (!FLAG_track_fields || !representation.IsSmi()) { |
660 // Skip updating write barrier if storing a smi. | 721 // Skip updating write barrier if storing a smi. |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 if (!global.is_null()) { | 1362 if (!global.is_null()) { |
1302 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); | 1363 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); |
1303 } | 1364 } |
1304 | 1365 |
1305 HandlerFrontendFooter(success, &miss); | 1366 HandlerFrontendFooter(success, &miss); |
1306 } | 1367 } |
1307 | 1368 |
1308 | 1369 |
1309 void BaseLoadStubCompiler::GenerateLoadField(Register reg, | 1370 void BaseLoadStubCompiler::GenerateLoadField(Register reg, |
1310 Handle<JSObject> holder, | 1371 Handle<JSObject> holder, |
1311 PropertyIndex field) { | 1372 PropertyIndex field, |
| 1373 Representation representation) { |
1312 if (!reg.is(receiver())) __ mov(receiver(), reg); | 1374 if (!reg.is(receiver())) __ mov(receiver(), reg); |
1313 if (kind() == Code::LOAD_IC) { | 1375 if (kind() == Code::LOAD_IC) { |
1314 LoadFieldStub stub(field.is_inobject(holder), | 1376 LoadFieldStub stub(field.is_inobject(holder), |
1315 field.translate(holder)); | 1377 field.translate(holder), |
| 1378 representation); |
1316 GenerateTailCall(masm(), stub.GetCode(isolate())); | 1379 GenerateTailCall(masm(), stub.GetCode(isolate())); |
1317 } else { | 1380 } else { |
1318 KeyedLoadFieldStub stub(field.is_inobject(holder), | 1381 KeyedLoadFieldStub stub(field.is_inobject(holder), |
1319 field.translate(holder)); | 1382 field.translate(holder), |
| 1383 representation); |
1320 GenerateTailCall(masm(), stub.GetCode(isolate())); | 1384 GenerateTailCall(masm(), stub.GetCode(isolate())); |
1321 } | 1385 } |
1322 } | 1386 } |
1323 | 1387 |
1324 | 1388 |
1325 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { | 1389 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { |
1326 // Return the constant value. | 1390 // Return the constant value. |
1327 __ LoadHeapObject(v0, value); | 1391 __ LoadHeapObject(v0, value); |
1328 __ Ret(); | 1392 __ Ret(); |
1329 } | 1393 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 | 1605 |
1542 const int argc = arguments().immediate(); | 1606 const int argc = arguments().immediate(); |
1543 | 1607 |
1544 // Get the receiver of the function from the stack into a0. | 1608 // Get the receiver of the function from the stack into a0. |
1545 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1609 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
1546 // Check that the receiver isn't a smi. | 1610 // Check that the receiver isn't a smi. |
1547 __ JumpIfSmi(a0, &miss, t0); | 1611 __ JumpIfSmi(a0, &miss, t0); |
1548 | 1612 |
1549 // Do the right check and compute the holder register. | 1613 // Do the right check and compute the holder register. |
1550 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1614 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); |
1551 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); | 1615 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), |
| 1616 index.translate(holder), Representation::Tagged()); |
1552 | 1617 |
1553 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1618 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1554 | 1619 |
1555 // Handle call cache miss. | 1620 // Handle call cache miss. |
1556 __ bind(&miss); | 1621 __ bind(&miss); |
1557 GenerateMissBranch(); | 1622 GenerateMissBranch(); |
1558 | 1623 |
1559 // Return the generated code. | 1624 // Return the generated code. |
1560 return GetCode(Code::FIELD, name); | 1625 return GetCode(Code::FIELD, name); |
1561 } | 1626 } |
(...skipping 2233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3795 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3860 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3796 } | 3861 } |
3797 } | 3862 } |
3798 | 3863 |
3799 | 3864 |
3800 #undef __ | 3865 #undef __ |
3801 | 3866 |
3802 } } // namespace v8::internal | 3867 } } // namespace v8::internal |
3803 | 3868 |
3804 #endif // V8_TARGET_ARCH_MIPS | 3869 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |