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

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

Issue 426633002: Encapsulate type in the PropertyHandlerCompiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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
« src/objects.cc ('K') | « src/stub-cache.cc ('k') | no next file » | 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_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 Handle<Code> code) { 626 Handle<Code> code) {
627 __ jmp(code, RelocInfo::CODE_TARGET); 627 __ jmp(code, RelocInfo::CODE_TARGET);
628 } 628 }
629 629
630 630
631 #undef __ 631 #undef __
632 #define __ ACCESS_MASM((masm())) 632 #define __ ACCESS_MASM((masm()))
633 633
634 634
635 Register PropertyHandlerCompiler::CheckPrototypes( 635 Register PropertyHandlerCompiler::CheckPrototypes(
636 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder, 636 Register object_reg, Handle<JSObject> holder, Register holder_reg,
637 Register holder_reg, Register scratch1, Register scratch2, 637 Register scratch1, Register scratch2, Handle<Name> name, Label* miss,
638 Handle<Name> name, Label* miss, PrototypeCheckType check) { 638 PrototypeCheckType check) {
639 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 639 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
640 640
641 // Make sure there's no overlap between holder and object registers. 641 // Make sure there's no overlap between holder and object registers.
642 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 642 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
643 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 643 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
644 && !scratch2.is(scratch1)); 644 && !scratch2.is(scratch1));
645 645
646 // Keep track of the current object in register reg. On the first 646 // Keep track of the current object in register reg. On the first
647 // iteration, reg is an alias for object_reg, on later iterations, 647 // iteration, reg is an alias for object_reg, on later iterations,
648 // it is an alias for holder_reg. 648 // it is an alias for holder_reg.
649 Register reg = object_reg; 649 Register reg = object_reg;
650 int depth = 0; 650 int depth = 0;
651 651
652 Handle<JSObject> current = Handle<JSObject>::null(); 652 Handle<JSObject> current = Handle<JSObject>::null();
653 if (type->IsConstant()) { 653 if (type()->IsConstant()) {
654 current = Handle<JSObject>::cast(type->AsConstant()->Value()); 654 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
655 } 655 }
656 Handle<JSObject> prototype = Handle<JSObject>::null(); 656 Handle<JSObject> prototype = Handle<JSObject>::null();
657 Handle<Map> current_map = receiver_map; 657 Handle<Map> current_map = receiver_map;
658 Handle<Map> holder_map(holder->map()); 658 Handle<Map> holder_map(holder->map());
659 // Traverse the prototype chain and check the maps in the prototype chain for 659 // Traverse the prototype chain and check the maps in the prototype chain for
660 // fast and global objects or do negative lookup for normal objects. 660 // fast and global objects or do negative lookup for normal objects.
661 while (!current_map.is_identical_to(holder_map)) { 661 while (!current_map.is_identical_to(holder_map)) {
662 ++depth; 662 ++depth;
663 663
664 // Only global objects and objects that do not require access 664 // Only global objects and objects that do not require access
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 if (!miss->is_unused()) { 758 if (!miss->is_unused()) {
759 Label success; 759 Label success;
760 __ jmp(&success); 760 __ jmp(&success);
761 GenerateRestoreName(masm(), miss, name); 761 GenerateRestoreName(masm(), miss, name);
762 TailCallBuiltin(masm(), MissBuiltin(kind())); 762 TailCallBuiltin(masm(), MissBuiltin(kind()));
763 __ bind(&success); 763 __ bind(&success);
764 } 764 }
765 } 765 }
766 766
767 767
768 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type, 768 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
769 Register object_reg,
770 Handle<JSObject> holder, 769 Handle<JSObject> holder,
771 Handle<Name> name, 770 Handle<Name> name,
772 Handle<Object> callback) { 771 Handle<Object> callback) {
773 Label miss; 772 Label miss;
774 773
775 Register reg = FrontendHeader(type, object_reg, holder, name, &miss); 774 Register reg = FrontendHeader(object_reg, holder, name, &miss);
776 775
777 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 776 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
778 ASSERT(!reg.is(scratch2())); 777 ASSERT(!reg.is(scratch2()));
779 ASSERT(!reg.is(scratch3())); 778 ASSERT(!reg.is(scratch3()));
780 ASSERT(!reg.is(scratch4())); 779 ASSERT(!reg.is(scratch4()));
781 780
782 // Load the properties dictionary. 781 // Load the properties dictionary.
783 Register dictionary = scratch4(); 782 Register dictionary = scratch4();
784 __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); 783 __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset));
785 784
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 867
869 868
870 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 869 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
871 // Return the constant value. 870 // Return the constant value.
872 __ Move(rax, value); 871 __ Move(rax, value);
873 __ ret(0); 872 __ ret(0);
874 } 873 }
875 874
876 875
877 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 876 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
878 Register holder_reg, Handle<Object> object, 877 Register holder_reg, Handle<JSObject> interceptor_holder,
879 Handle<JSObject> interceptor_holder, LookupResult* lookup, 878 LookupResult* lookup, Handle<Name> name) {
880 Handle<Name> name) {
881 ASSERT(interceptor_holder->HasNamedInterceptor()); 879 ASSERT(interceptor_holder->HasNamedInterceptor());
882 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 880 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
883 881
884 // So far the most popular follow ups for interceptor loads are FIELD 882 // So far the most popular follow ups for interceptor loads are FIELD
885 // and CALLBACKS, so inline only them, other cases may be added 883 // and CALLBACKS, so inline only them, other cases may be added
886 // later. 884 // later.
887 bool compile_followup_inline = false; 885 bool compile_followup_inline = false;
888 if (lookup->IsFound() && lookup->IsCacheable()) { 886 if (lookup->IsFound() && lookup->IsCacheable()) {
889 if (lookup->IsField()) { 887 if (lookup->IsField()) {
890 compile_followup_inline = true; 888 compile_followup_inline = true;
891 } else if (lookup->type() == CALLBACKS && 889 } else if (lookup->type() == CALLBACKS &&
892 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 890 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
893 ExecutableAccessorInfo* callback = 891 Handle<ExecutableAccessorInfo> callback(
894 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); 892 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
895 compile_followup_inline = callback->getter() != NULL && 893 compile_followup_inline =
896 callback->IsCompatibleReceiver(*object); 894 callback->getter() != NULL &&
895 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
896 type());
897 } 897 }
898 } 898 }
899 899
900 if (compile_followup_inline) { 900 if (compile_followup_inline) {
901 // Compile the interceptor call, followed by inline code to load the 901 // Compile the interceptor call, followed by inline code to load the
902 // property from further up the prototype chain if the call fails. 902 // property from further up the prototype chain if the call fails.
903 // Check that the maps haven't changed. 903 // Check that the maps haven't changed.
904 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 904 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
905 905
906 // Preserve the receiver register explicitly whenever it is different from 906 // Preserve the receiver register explicitly whenever it is different from
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 960 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
961 __ TailCallExternalReference( 961 __ TailCallExternalReference(
962 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 962 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
963 } 963 }
964 } 964 }
965 965
966 966
967 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 967 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
968 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 968 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
969 Handle<ExecutableAccessorInfo> callback) { 969 Handle<ExecutableAccessorInfo> callback) {
970 Register holder_reg = 970 Register holder_reg = Frontend(receiver(), holder, name);
971 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
972 971
973 __ PopReturnAddressTo(scratch1()); 972 __ PopReturnAddressTo(scratch1());
974 __ Push(receiver()); 973 __ Push(receiver());
975 __ Push(holder_reg); 974 __ Push(holder_reg);
976 __ Push(callback); // callback info 975 __ Push(callback); // callback info
977 __ Push(name); 976 __ Push(name);
978 __ Push(value()); 977 __ Push(value());
979 __ PushReturnAddressFrom(scratch1()); 978 __ PushReturnAddressFrom(scratch1());
980 979
981 // Do tail-call to the runtime system. 980 // Do tail-call to the runtime system.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 __ bind(&miss); 1095 __ bind(&miss);
1097 1096
1098 TailCallBuiltin(masm(), MissBuiltin(kind())); 1097 TailCallBuiltin(masm(), MissBuiltin(kind()));
1099 1098
1100 // Return the generated code. 1099 // Return the generated code.
1101 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 1100 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1102 } 1101 }
1103 1102
1104 1103
1105 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1104 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1106 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) { 1105 Handle<JSObject> last, Handle<Name> name) {
1107 NonexistentFrontend(type, last, name); 1106 NonexistentFrontend(last, name);
1108 1107
1109 // Return undefined if maps of the full prototype chain are still the 1108 // Return undefined if maps of the full prototype chain are still the
1110 // same and no global property with this name contains a value. 1109 // same and no global property with this name contains a value.
1111 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1110 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1112 __ ret(0); 1111 __ ret(0);
1113 1112
1114 // Return the generated code. 1113 // Return the generated code.
1115 return GetCode(kind(), Code::FAST, name); 1114 return GetCode(kind(), Code::FAST, name);
1116 } 1115 }
1117 1116
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 } 1184 }
1186 __ ret(0); 1185 __ ret(0);
1187 } 1186 }
1188 1187
1189 1188
1190 #undef __ 1189 #undef __
1191 #define __ ACCESS_MASM(masm()) 1190 #define __ ACCESS_MASM(masm())
1192 1191
1193 1192
1194 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1193 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1195 Handle<HeapType> type, Handle<GlobalObject> global, 1194 Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name,
1196 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { 1195 bool is_dont_delete) {
1197 Label miss; 1196 Label miss;
1198 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since 1197 FrontendHeader(receiver(), global, name, &miss);
1199 // rax is used as receiver(), which we would otherwise clobber before a
1200 // potential miss.
1201 FrontendHeader(type, receiver(), global, name, &miss);
1202 1198
1203 // Get the value from the cell. 1199 // Get the value from the cell.
1204 __ Move(rbx, cell); 1200 Register result = StoreIC::ValueRegister();
1205 __ movp(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); 1201 __ Move(result, cell);
1202 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
1206 1203
1207 // Check for deleted property if property can actually be deleted. 1204 // Check for deleted property if property can actually be deleted.
1208 if (!is_dont_delete) { 1205 if (!is_dont_delete) {
1209 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 1206 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
1210 __ j(equal, &miss); 1207 __ j(equal, &miss);
1211 } else if (FLAG_debug_code) { 1208 } else if (FLAG_debug_code) {
1212 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 1209 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
1213 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 1210 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
1214 } 1211 }
1215 1212
1216 Counters* counters = isolate()->counters(); 1213 Counters* counters = isolate()->counters();
1217 __ IncrementCounter(counters->named_load_global_stub(), 1); 1214 __ IncrementCounter(counters->named_load_global_stub(), 1);
1218 __ movp(rax, rbx);
1219 __ ret(0); 1215 __ ret(0);
1220 1216
1221 FrontendFooter(name, &miss); 1217 FrontendFooter(name, &miss);
1222 1218
1223 // Return the generated code. 1219 // Return the generated code.
1224 return GetCode(kind(), Code::NORMAL, name); 1220 return GetCode(kind(), Code::NORMAL, name);
1225 } 1221 }
1226 1222
1227 1223
1228 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, 1224 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 // ----------------------------------- 1317 // -----------------------------------
1322 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1318 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1323 } 1319 }
1324 1320
1325 1321
1326 #undef __ 1322 #undef __
1327 1323
1328 } } // namespace v8::internal 1324 } } // namespace v8::internal
1329 1325
1330 #endif // V8_TARGET_ARCH_X64 1326 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/objects.cc ('K') | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698