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

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

Issue 10534090: Rollback of r11719, r11717, r11716, r11714, r11700, r11699, r11697, r11695, r11694 in trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 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 | « src/stub-cache.h ('k') | test/cctest/test-api.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 // 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 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 __ Jump(code, RelocInfo::CODE_TARGET); 724 __ Jump(code, RelocInfo::CODE_TARGET);
725 } 725 }
726 726
727 727
728 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 728 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
729 // but may be destroyed if store is successful. 729 // but may be destroyed if store is successful.
730 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 730 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
731 Handle<JSObject> object, 731 Handle<JSObject> object,
732 int index, 732 int index,
733 Handle<Map> transition, 733 Handle<Map> transition,
734 Handle<String> name,
735 Register receiver_reg, 734 Register receiver_reg,
736 Register name_reg, 735 Register name_reg,
737 Register scratch1, 736 Register scratch,
738 Register scratch2,
739 Label* miss_label) { 737 Label* miss_label) {
740 LookupResult lookup(masm->isolate());
741 object->Lookup(*name, &lookup);
742 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
743 // In sloppy mode, we could just return the value and be done. However, we
744 // might be in strict mode, where we have to throw. Since we cannot tell,
745 // go into slow case unconditionally.
746 __ jmp(miss_label);
747 return;
748 }
749
750 // Check that the map of the object hasn't changed. 738 // Check that the map of the object hasn't changed.
751 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS 739 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
752 : REQUIRE_EXACT_MAP; 740 : REQUIRE_EXACT_MAP;
753 __ CheckMap(receiver_reg, Handle<Map>(object->map()), 741 __ CheckMap(receiver_reg, Handle<Map>(object->map()),
754 miss_label, DO_SMI_CHECK, mode); 742 miss_label, DO_SMI_CHECK, mode);
755 743
756 // Perform global security token check if needed. 744 // Perform global security token check if needed.
757 if (object->IsJSGlobalProxy()) { 745 if (object->IsJSGlobalProxy()) {
758 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); 746 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
759 }
760
761 // Check that we are allowed to write this.
762 if (!transition.is_null() && object->GetPrototype()->IsJSObject()) {
763 JSObject* holder;
764 if (lookup.IsFound()) {
765 holder = lookup.holder();
766 } else {
767 // Find the top object.
768 holder = *object;
769 do {
770 holder = JSObject::cast(holder->GetPrototype());
771 } while (holder->GetPrototype()->IsJSObject());
772 }
773 // We need an extra register, push
774 __ push(name_reg);
775 Label miss_pop, done_check;
776 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
777 scratch1, scratch2, name, &miss_pop);
778 __ jmp(&done_check);
779 __ bind(&miss_pop);
780 __ pop(name_reg);
781 __ jmp(miss_label);
782 __ bind(&done_check);
783 __ pop(name_reg);
784 } 747 }
785 748
786 // Stub never generated for non-global objects that require access 749 // Stub never generated for non-global objects that require access
787 // checks. 750 // checks.
788 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 751 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
789 752
790 // Perform map transition for the receiver if necessary. 753 // Perform map transition for the receiver if necessary.
791 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 754 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
792 // The properties must be extended before we can store the value. 755 // The properties must be extended before we can store the value.
793 // We jump to a runtime call that extends the properties array. 756 // We jump to a runtime call that extends the properties array.
794 __ pop(scratch1); // Return address. 757 __ pop(scratch); // Return address.
795 __ push(receiver_reg); 758 __ push(receiver_reg);
796 __ Push(transition); 759 __ Push(transition);
797 __ push(rax); 760 __ push(rax);
798 __ push(scratch1); 761 __ push(scratch);
799 __ TailCallExternalReference( 762 __ TailCallExternalReference(
800 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 763 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
801 masm->isolate()), 764 masm->isolate()),
802 3, 765 3,
803 1); 766 1);
804 return; 767 return;
805 } 768 }
806 769
807 if (!transition.is_null()) { 770 if (!transition.is_null()) {
808 // Update the map of the object. 771 // Update the map of the object.
809 __ Move(scratch1, transition); 772 __ Move(scratch, transition);
810 __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 773 __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch);
811 774
812 // Update the write barrier for the map field and pass the now unused 775 // Update the write barrier for the map field and pass the now unused
813 // name_reg as scratch register. 776 // name_reg as scratch register.
814 __ RecordWriteField(receiver_reg, 777 __ RecordWriteField(receiver_reg,
815 HeapObject::kMapOffset, 778 HeapObject::kMapOffset,
816 scratch1, 779 scratch,
817 name_reg, 780 name_reg,
818 kDontSaveFPRegs, 781 kDontSaveFPRegs,
819 OMIT_REMEMBERED_SET, 782 OMIT_REMEMBERED_SET,
820 OMIT_SMI_CHECK); 783 OMIT_SMI_CHECK);
821 } 784 }
822 785
823 // Adjust for the number of properties stored in the object. Even in the 786 // Adjust for the number of properties stored in the object. Even in the
824 // face of a transition we can use the old map here because the size of the 787 // face of a transition we can use the old map here because the size of the
825 // object and the number of in-object properties is not going to change. 788 // object and the number of in-object properties is not going to change.
826 index -= object->map()->inobject_properties(); 789 index -= object->map()->inobject_properties();
827 790
828 if (index < 0) { 791 if (index < 0) {
829 // Set the property straight into the object. 792 // Set the property straight into the object.
830 int offset = object->map()->instance_size() + (index * kPointerSize); 793 int offset = object->map()->instance_size() + (index * kPointerSize);
831 __ movq(FieldOperand(receiver_reg, offset), rax); 794 __ movq(FieldOperand(receiver_reg, offset), rax);
832 795
833 // Update the write barrier for the array address. 796 // Update the write barrier for the array address.
834 // Pass the value being stored in the now unused name_reg. 797 // Pass the value being stored in the now unused name_reg.
835 __ movq(name_reg, rax); 798 __ movq(name_reg, rax);
836 __ RecordWriteField( 799 __ RecordWriteField(
837 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs); 800 receiver_reg, offset, name_reg, scratch, kDontSaveFPRegs);
838 } else { 801 } else {
839 // Write to the properties array. 802 // Write to the properties array.
840 int offset = index * kPointerSize + FixedArray::kHeaderSize; 803 int offset = index * kPointerSize + FixedArray::kHeaderSize;
841 // Get the properties array (optimistically). 804 // Get the properties array (optimistically).
842 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 805 __ movq(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
843 __ movq(FieldOperand(scratch1, offset), rax); 806 __ movq(FieldOperand(scratch, offset), rax);
844 807
845 // Update the write barrier for the array address. 808 // Update the write barrier for the array address.
846 // Pass the value being stored in the now unused name_reg. 809 // Pass the value being stored in the now unused name_reg.
847 __ movq(name_reg, rax); 810 __ movq(name_reg, rax);
848 __ RecordWriteField( 811 __ RecordWriteField(
849 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); 812 scratch, offset, name_reg, receiver_reg, kDontSaveFPRegs);
850 } 813 }
851 814
852 // Return the value (register rax). 815 // Return the value (register rax).
853 __ ret(0); 816 __ ret(0);
854 } 817 }
855 818
856 819
857 // Generate code to check that a global property cell is empty. Create 820 // Generate code to check that a global property cell is empty. Create
858 // the property cell at compilation time if no cell exists for the 821 // the property cell at compilation time if no cell exists for the
859 // property. 822 // property.
(...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 Handle<String> name) { 2314 Handle<String> name) {
2352 // ----------- S t a t e ------------- 2315 // ----------- S t a t e -------------
2353 // -- rax : value 2316 // -- rax : value
2354 // -- rcx : name 2317 // -- rcx : name
2355 // -- rdx : receiver 2318 // -- rdx : receiver
2356 // -- rsp[0] : return address 2319 // -- rsp[0] : return address
2357 // ----------------------------------- 2320 // -----------------------------------
2358 Label miss; 2321 Label miss;
2359 2322
2360 // Generate store field code. Preserves receiver and name on jump to miss. 2323 // Generate store field code. Preserves receiver and name on jump to miss.
2361 GenerateStoreField(masm(), 2324 GenerateStoreField(masm(), object, index, transition, rdx, rcx, rbx, &miss);
2362 object,
2363 index,
2364 transition,
2365 name,
2366 rdx, rcx, rbx, rdi,
2367 &miss);
2368 2325
2369 // Handle store cache miss. 2326 // Handle store cache miss.
2370 __ bind(&miss); 2327 __ bind(&miss);
2371 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2328 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2372 __ Jump(ic, RelocInfo::CODE_TARGET); 2329 __ Jump(ic, RelocInfo::CODE_TARGET);
2373 2330
2374 // Return the generated code. 2331 // Return the generated code.
2375 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); 2332 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2376 } 2333 }
2377 2334
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2530 Label miss; 2487 Label miss;
2531 2488
2532 Counters* counters = isolate()->counters(); 2489 Counters* counters = isolate()->counters();
2533 __ IncrementCounter(counters->keyed_store_field(), 1); 2490 __ IncrementCounter(counters->keyed_store_field(), 1);
2534 2491
2535 // Check that the name has not changed. 2492 // Check that the name has not changed.
2536 __ Cmp(rcx, name); 2493 __ Cmp(rcx, name);
2537 __ j(not_equal, &miss); 2494 __ j(not_equal, &miss);
2538 2495
2539 // Generate store field code. Preserves receiver and name on jump to miss. 2496 // Generate store field code. Preserves receiver and name on jump to miss.
2540 GenerateStoreField(masm(), 2497 GenerateStoreField(masm(), object, index, transition, rdx, rcx, rbx, &miss);
2541 object,
2542 index,
2543 transition,
2544 name,
2545 rdx, rcx, rbx, rdi,
2546 &miss);
2547 2498
2548 // Handle store cache miss. 2499 // Handle store cache miss.
2549 __ bind(&miss); 2500 __ bind(&miss);
2550 __ DecrementCounter(counters->keyed_store_field(), 1); 2501 __ DecrementCounter(counters->keyed_store_field(), 1);
2551 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2502 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2552 __ Jump(ic, RelocInfo::CODE_TARGET); 2503 __ Jump(ic, RelocInfo::CODE_TARGET);
2553 2504
2554 // Return the generated code. 2505 // Return the generated code.
2555 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); 2506 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2556 } 2507 }
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after
3911 __ jmp(ic_slow, RelocInfo::CODE_TARGET); 3862 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3912 } 3863 }
3913 } 3864 }
3914 3865
3915 3866
3916 #undef __ 3867 #undef __
3917 3868
3918 } } // namespace v8::internal 3869 } } // namespace v8::internal
3919 3870
3920 #endif // V8_TARGET_ARCH_X64 3871 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698