Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: src/arm/stub-cache-arm.cc

Issue 300283002: Introduce FieldIndex to unify and abstract property/field offset (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix mutable boxed double runtime function Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm64/stub-cache-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/ic-inl.h" 9 #include "src/ic-inl.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 Register scratch1, 566 Register scratch1,
567 Register scratch2, 567 Register scratch2,
568 Label* miss_label) { 568 Label* miss_label) {
569 // r0 : value 569 // r0 : value
570 Label exit; 570 Label exit;
571 571
572 // Stub never generated for non-global objects that require access 572 // Stub never generated for non-global objects that require access
573 // checks. 573 // checks.
574 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 574 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
575 575
576 int index = lookup->GetFieldIndex().field_index(); 576 FieldIndex index = lookup->GetFieldIndex();
577
578 // Adjust for the number of properties stored in the object. Even in the
579 // face of a transition we can use the old map here because the size of the
580 // object and the number of in-object properties is not going to change.
581 index -= object->map()->inobject_properties();
582 577
583 Representation representation = lookup->representation(); 578 Representation representation = lookup->representation();
584 ASSERT(!representation.IsNone()); 579 ASSERT(!representation.IsNone());
585 if (representation.IsSmi()) { 580 if (representation.IsSmi()) {
586 __ JumpIfNotSmi(value_reg, miss_label); 581 __ JumpIfNotSmi(value_reg, miss_label);
587 } else if (representation.IsHeapObject()) { 582 } else if (representation.IsHeapObject()) {
588 __ JumpIfSmi(value_reg, miss_label); 583 __ JumpIfSmi(value_reg, miss_label);
589 HeapType* field_type = lookup->GetFieldType(); 584 HeapType* field_type = lookup->GetFieldType();
590 HeapType::Iterator<Map> it = field_type->Classes(); 585 HeapType::Iterator<Map> it = field_type->Classes();
591 if (!it.Done()) { 586 if (!it.Done()) {
592 __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 587 __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
593 Label do_store; 588 Label do_store;
594 while (true) { 589 while (true) {
595 __ CompareMap(scratch1, it.Current(), &do_store); 590 __ CompareMap(scratch1, it.Current(), &do_store);
596 it.Advance(); 591 it.Advance();
597 if (it.Done()) { 592 if (it.Done()) {
598 __ b(ne, miss_label); 593 __ b(ne, miss_label);
599 break; 594 break;
600 } 595 }
601 __ b(eq, &do_store); 596 __ b(eq, &do_store);
602 } 597 }
603 __ bind(&do_store); 598 __ bind(&do_store);
604 } 599 }
605 } else if (representation.IsDouble()) { 600 } else if (representation.IsDouble()) {
606 // Load the double storage. 601 // Load the double storage.
607 if (index < 0) { 602 if (index.is_inobject()) {
608 int offset = object->map()->instance_size() + (index * kPointerSize); 603 __ ldr(scratch1, FieldMemOperand(receiver_reg, index.offset()));
609 __ ldr(scratch1, FieldMemOperand(receiver_reg, offset));
610 } else { 604 } else {
611 __ ldr(scratch1, 605 __ ldr(scratch1,
612 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 606 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
613 int offset = index * kPointerSize + FixedArray::kHeaderSize; 607 __ ldr(scratch1, FieldMemOperand(scratch1, index.offset()));
614 __ ldr(scratch1, FieldMemOperand(scratch1, offset));
615 } 608 }
616 609
617 // Store the value into the storage. 610 // Store the value into the storage.
618 Label do_store, heap_number; 611 Label do_store, heap_number;
619 __ JumpIfNotSmi(value_reg, &heap_number); 612 __ JumpIfNotSmi(value_reg, &heap_number);
620 __ SmiUntag(scratch2, value_reg); 613 __ SmiUntag(scratch2, value_reg);
621 __ vmov(s0, scratch2); 614 __ vmov(s0, scratch2);
622 __ vcvt_f64_s32(d0, s0); 615 __ vcvt_f64_s32(d0, s0);
623 __ jmp(&do_store); 616 __ jmp(&do_store);
624 617
625 __ bind(&heap_number); 618 __ bind(&heap_number);
626 __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, 619 __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex,
627 miss_label, DONT_DO_SMI_CHECK); 620 miss_label, DONT_DO_SMI_CHECK);
628 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 621 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
629 622
630 __ bind(&do_store); 623 __ bind(&do_store);
631 __ vstr(d0, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); 624 __ vstr(d0, FieldMemOperand(scratch1, HeapNumber::kValueOffset));
632 // Return the value (register r0). 625 // Return the value (register r0).
633 ASSERT(value_reg.is(r0)); 626 ASSERT(value_reg.is(r0));
634 __ Ret(); 627 __ Ret();
635 return; 628 return;
636 } 629 }
637 630
638 // TODO(verwaest): Share this code as a code stub. 631 // TODO(verwaest): Share this code as a code stub.
639 SmiCheck smi_check = representation.IsTagged() 632 SmiCheck smi_check = representation.IsTagged()
640 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 633 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
641 if (index < 0) { 634 if (index.is_inobject()) {
642 // Set the property straight into the object. 635 // Set the property straight into the object.
643 int offset = object->map()->instance_size() + (index * kPointerSize); 636 __ str(value_reg, FieldMemOperand(receiver_reg, index.offset()));
644 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
645 637
646 if (!representation.IsSmi()) { 638 if (!representation.IsSmi()) {
647 // Skip updating write barrier if storing a smi. 639 // Skip updating write barrier if storing a smi.
648 __ JumpIfSmi(value_reg, &exit); 640 __ JumpIfSmi(value_reg, &exit);
649 641
650 // Update the write barrier for the array address. 642 // Update the write barrier for the array address.
651 // Pass the now unused name_reg as a scratch register. 643 // Pass the now unused name_reg as a scratch register.
652 __ mov(name_reg, value_reg); 644 __ mov(name_reg, value_reg);
653 __ RecordWriteField(receiver_reg, 645 __ RecordWriteField(receiver_reg,
654 offset, 646 index.offset(),
655 name_reg, 647 name_reg,
656 scratch1, 648 scratch1,
657 kLRHasNotBeenSaved, 649 kLRHasNotBeenSaved,
658 kDontSaveFPRegs, 650 kDontSaveFPRegs,
659 EMIT_REMEMBERED_SET, 651 EMIT_REMEMBERED_SET,
660 smi_check); 652 smi_check);
661 } 653 }
662 } else { 654 } else {
663 // Write to the properties array. 655 // Write to the properties array.
664 int offset = index * kPointerSize + FixedArray::kHeaderSize;
665 // Get the properties array 656 // Get the properties array
666 __ ldr(scratch1, 657 __ ldr(scratch1,
667 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 658 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
668 __ str(value_reg, FieldMemOperand(scratch1, offset)); 659 __ str(value_reg, FieldMemOperand(scratch1, index.offset()));
669 660
670 if (!representation.IsSmi()) { 661 if (!representation.IsSmi()) {
671 // Skip updating write barrier if storing a smi. 662 // Skip updating write barrier if storing a smi.
672 __ JumpIfSmi(value_reg, &exit); 663 __ JumpIfSmi(value_reg, &exit);
673 664
674 // Update the write barrier for the array address. 665 // Update the write barrier for the array address.
675 // Ok to clobber receiver_reg and name_reg, since we return. 666 // Ok to clobber receiver_reg and name_reg, since we return.
676 __ mov(name_reg, value_reg); 667 __ mov(name_reg, value_reg);
677 __ RecordWriteField(scratch1, 668 __ RecordWriteField(scratch1,
678 offset, 669 index.offset(),
679 name_reg, 670 name_reg,
680 receiver_reg, 671 receiver_reg,
681 kLRHasNotBeenSaved, 672 kLRHasNotBeenSaved,
682 kDontSaveFPRegs, 673 kDontSaveFPRegs,
683 EMIT_REMEMBERED_SET, 674 EMIT_REMEMBERED_SET,
684 smi_check); 675 smi_check);
685 } 676 }
686 } 677 }
687 678
688 // Return the value (register r0). 679 // Return the value (register r0).
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 __ b(ne, &miss); 990 __ b(ne, &miss);
1000 } 991 }
1001 992
1002 HandlerFrontendFooter(name, &miss); 993 HandlerFrontendFooter(name, &miss);
1003 return reg; 994 return reg;
1004 } 995 }
1005 996
1006 997
1007 void LoadStubCompiler::GenerateLoadField(Register reg, 998 void LoadStubCompiler::GenerateLoadField(Register reg,
1008 Handle<JSObject> holder, 999 Handle<JSObject> holder,
1009 PropertyIndex field, 1000 FieldIndex field,
1010 Representation representation) { 1001 Representation representation) {
1011 if (!reg.is(receiver())) __ mov(receiver(), reg); 1002 if (!reg.is(receiver())) __ mov(receiver(), reg);
1012 if (kind() == Code::LOAD_IC) { 1003 if (kind() == Code::LOAD_IC) {
1013 LoadFieldStub stub(isolate(), 1004 LoadFieldStub stub(isolate(), field);
1014 field.is_inobject(holder),
1015 field.translate(holder),
1016 representation);
1017 GenerateTailCall(masm(), stub.GetCode()); 1005 GenerateTailCall(masm(), stub.GetCode());
1018 } else { 1006 } else {
1019 KeyedLoadFieldStub stub(isolate(), 1007 KeyedLoadFieldStub stub(isolate(), field);
1020 field.is_inobject(holder),
1021 field.translate(holder),
1022 representation);
1023 GenerateTailCall(masm(), stub.GetCode()); 1008 GenerateTailCall(masm(), stub.GetCode());
1024 } 1009 }
1025 } 1010 }
1026 1011
1027 1012
1028 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1013 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1029 // Return the constant value. 1014 // Return the constant value.
1030 __ Move(r0, value); 1015 __ Move(r0, value);
1031 __ Ret(); 1016 __ Ret();
1032 } 1017 }
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 // ----------------------------------- 1507 // -----------------------------------
1523 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1508 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1524 } 1509 }
1525 1510
1526 1511
1527 #undef __ 1512 #undef __
1528 1513
1529 } } // namespace v8::internal 1514 } } // namespace v8::internal
1530 1515
1531 #endif // V8_TARGET_ARCH_ARM 1516 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/stub-cache-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698