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

Side by Side Diff: src/ia32/stub-cache-ia32.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
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_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 Handle<Code> code) { 686 Handle<Code> code) {
687 __ jmp(code, RelocInfo::CODE_TARGET); 687 __ jmp(code, RelocInfo::CODE_TARGET);
688 } 688 }
689 689
690 690
691 #undef __ 691 #undef __
692 #define __ ACCESS_MASM(masm()) 692 #define __ ACCESS_MASM(masm())
693 693
694 694
695 Register PropertyHandlerCompiler::CheckPrototypes( 695 Register PropertyHandlerCompiler::CheckPrototypes(
696 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder, 696 Register object_reg, Handle<JSObject> holder, Register holder_reg,
697 Register holder_reg, Register scratch1, Register scratch2, 697 Register scratch1, Register scratch2, Handle<Name> name, Label* miss,
698 Handle<Name> name, Label* miss, PrototypeCheckType check) { 698 PrototypeCheckType check) {
699 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 699 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
700 700
701 // Make sure there's no overlap between holder and object registers. 701 // Make sure there's no overlap between holder and object registers.
702 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 702 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
703 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 703 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
704 && !scratch2.is(scratch1)); 704 && !scratch2.is(scratch1));
705 705
706 // Keep track of the current object in register reg. 706 // Keep track of the current object in register reg.
707 Register reg = object_reg; 707 Register reg = object_reg;
708 int depth = 0; 708 int depth = 0;
709 709
710 Handle<JSObject> current = Handle<JSObject>::null(); 710 Handle<JSObject> current = Handle<JSObject>::null();
711 if (type->IsConstant()) current = 711 if (type()->IsConstant())
712 Handle<JSObject>::cast(type->AsConstant()->Value()); 712 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
713 Handle<JSObject> prototype = Handle<JSObject>::null(); 713 Handle<JSObject> prototype = Handle<JSObject>::null();
714 Handle<Map> current_map = receiver_map; 714 Handle<Map> current_map = receiver_map;
715 Handle<Map> holder_map(holder->map()); 715 Handle<Map> holder_map(holder->map());
716 // Traverse the prototype chain and check the maps in the prototype chain for 716 // Traverse the prototype chain and check the maps in the prototype chain for
717 // fast and global objects or do negative lookup for normal objects. 717 // fast and global objects or do negative lookup for normal objects.
718 while (!current_map.is_identical_to(holder_map)) { 718 while (!current_map.is_identical_to(holder_map)) {
719 ++depth; 719 ++depth;
720 720
721 // Only global objects and objects that do not require access 721 // Only global objects and objects that do not require access
722 // checks are allowed in stubs. 722 // checks are allowed in stubs.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 if (!miss->is_unused()) { 817 if (!miss->is_unused()) {
818 Label success; 818 Label success;
819 __ jmp(&success); 819 __ jmp(&success);
820 GenerateRestoreName(masm(), miss, name); 820 GenerateRestoreName(masm(), miss, name);
821 TailCallBuiltin(masm(), MissBuiltin(kind())); 821 TailCallBuiltin(masm(), MissBuiltin(kind()));
822 __ bind(&success); 822 __ bind(&success);
823 } 823 }
824 } 824 }
825 825
826 826
827 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type, 827 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
828 Register object_reg,
829 Handle<JSObject> holder, 828 Handle<JSObject> holder,
830 Handle<Name> name, 829 Handle<Name> name,
831 Handle<Object> callback) { 830 Handle<Object> callback) {
832 Label miss; 831 Label miss;
833 832
834 Register reg = FrontendHeader(type, object_reg, holder, name, &miss); 833 Register reg = FrontendHeader(object_reg, holder, name, &miss);
835 834
836 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 835 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
837 ASSERT(!reg.is(scratch2())); 836 ASSERT(!reg.is(scratch2()));
838 ASSERT(!reg.is(scratch3())); 837 ASSERT(!reg.is(scratch3()));
839 Register dictionary = scratch1(); 838 Register dictionary = scratch1();
840 bool must_preserve_dictionary_reg = reg.is(dictionary); 839 bool must_preserve_dictionary_reg = reg.is(dictionary);
841 840
842 // Load the properties dictionary. 841 // Load the properties dictionary.
843 if (must_preserve_dictionary_reg) { 842 if (must_preserve_dictionary_reg) {
844 __ push(dictionary); 843 __ push(dictionary);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 936
938 937
939 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 938 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
940 // Return the constant value. 939 // Return the constant value.
941 __ LoadObject(eax, value); 940 __ LoadObject(eax, value);
942 __ ret(0); 941 __ ret(0);
943 } 942 }
944 943
945 944
946 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 945 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
947 Register holder_reg, Handle<Object> object, 946 Register holder_reg, Handle<JSObject> interceptor_holder,
948 Handle<JSObject> interceptor_holder, LookupResult* lookup, 947 LookupResult* lookup, Handle<Name> name) {
949 Handle<Name> name) {
950 ASSERT(interceptor_holder->HasNamedInterceptor()); 948 ASSERT(interceptor_holder->HasNamedInterceptor());
951 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 949 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
952 950
953 // So far the most popular follow ups for interceptor loads are FIELD 951 // So far the most popular follow ups for interceptor loads are FIELD
954 // and CALLBACKS, so inline only them, other cases may be added 952 // and CALLBACKS, so inline only them, other cases may be added
955 // later. 953 // later.
956 bool compile_followup_inline = false; 954 bool compile_followup_inline = false;
957 if (lookup->IsFound() && lookup->IsCacheable()) { 955 if (lookup->IsFound() && lookup->IsCacheable()) {
958 if (lookup->IsField()) { 956 if (lookup->IsField()) {
959 compile_followup_inline = true; 957 compile_followup_inline = true;
960 } else if (lookup->type() == CALLBACKS && 958 } else if (lookup->type() == CALLBACKS &&
961 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 959 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
962 ExecutableAccessorInfo* callback = 960 Handle<ExecutableAccessorInfo> callback(
963 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); 961 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
964 compile_followup_inline = callback->getter() != NULL && 962 compile_followup_inline =
965 callback->IsCompatibleReceiver(*object); 963 callback->getter() != NULL &&
964 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
965 type());
966 } 966 }
967 } 967 }
968 968
969 if (compile_followup_inline) { 969 if (compile_followup_inline) {
970 // Compile the interceptor call, followed by inline code to load the 970 // Compile the interceptor call, followed by inline code to load the
971 // property from further up the prototype chain if the call fails. 971 // property from further up the prototype chain if the call fails.
972 // Check that the maps haven't changed. 972 // Check that the maps haven't changed.
973 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 973 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
974 974
975 // Preserve the receiver register explicitly whenever it is different from 975 // Preserve the receiver register explicitly whenever it is different from
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 isolate()); 1037 isolate());
1038 __ TailCallExternalReference( 1038 __ TailCallExternalReference(
1039 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 1039 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
1040 } 1040 }
1041 } 1041 }
1042 1042
1043 1043
1044 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 1044 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1045 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 1045 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
1046 Handle<ExecutableAccessorInfo> callback) { 1046 Handle<ExecutableAccessorInfo> callback) {
1047 Register holder_reg = 1047 Register holder_reg = Frontend(receiver(), holder, name);
1048 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1049 1048
1050 __ pop(scratch1()); // remove the return address 1049 __ pop(scratch1()); // remove the return address
1051 __ push(receiver()); 1050 __ push(receiver());
1052 __ push(holder_reg); 1051 __ push(holder_reg);
1053 __ Push(callback); 1052 __ Push(callback);
1054 __ Push(name); 1053 __ Push(name);
1055 __ push(value()); 1054 __ push(value());
1056 __ push(scratch1()); // restore return address 1055 __ push(scratch1()); // restore return address
1057 1056
1058 // Do tail-call to the runtime system. 1057 // Do tail-call to the runtime system.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 } 1165 }
1167 __ bind(&miss); 1166 __ bind(&miss);
1168 TailCallBuiltin(masm(), MissBuiltin(kind())); 1167 TailCallBuiltin(masm(), MissBuiltin(kind()));
1169 1168
1170 // Return the generated code. 1169 // Return the generated code.
1171 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 1170 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1172 } 1171 }
1173 1172
1174 1173
1175 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1174 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1176 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) { 1175 Handle<JSObject> last, Handle<Name> name) {
1177 NonexistentFrontend(type, last, name); 1176 NonexistentFrontend(last, name);
1178 1177
1179 // Return undefined if maps of the full prototype chain are still the 1178 // Return undefined if maps of the full prototype chain are still the
1180 // same and no global property with this name contains a value. 1179 // same and no global property with this name contains a value.
1181 __ mov(eax, isolate()->factory()->undefined_value()); 1180 __ mov(eax, isolate()->factory()->undefined_value());
1182 __ ret(0); 1181 __ ret(0);
1183 1182
1184 // Return the generated code. 1183 // Return the generated code.
1185 return GetCode(kind(), Code::FAST, name); 1184 return GetCode(kind(), Code::FAST, name);
1186 } 1185 }
1187 1186
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 } 1249 }
1251 __ ret(0); 1250 __ ret(0);
1252 } 1251 }
1253 1252
1254 1253
1255 #undef __ 1254 #undef __
1256 #define __ ACCESS_MASM(masm()) 1255 #define __ ACCESS_MASM(masm())
1257 1256
1258 1257
1259 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1258 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1260 Handle<HeapType> type, Handle<GlobalObject> global, 1259 Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name,
1261 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { 1260 bool is_dont_delete) {
1262 Label miss; 1261 Label miss;
1263 1262
1264 FrontendHeader(type, receiver(), global, name, &miss); 1263 FrontendHeader(receiver(), global, name, &miss);
1265 // Get the value from the cell. 1264 // Get the value from the cell.
1265 Register result = StoreIC::ValueRegister();
1266 if (masm()->serializer_enabled()) { 1266 if (masm()->serializer_enabled()) {
1267 __ mov(eax, Immediate(cell)); 1267 __ mov(result, Immediate(cell));
1268 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); 1268 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
1269 } else { 1269 } else {
1270 __ mov(eax, Operand::ForCell(cell)); 1270 __ mov(result, Operand::ForCell(cell));
1271 } 1271 }
1272 1272
1273 // Check for deleted property if property can actually be deleted. 1273 // Check for deleted property if property can actually be deleted.
1274 if (!is_dont_delete) { 1274 if (!is_dont_delete) {
1275 __ cmp(eax, factory()->the_hole_value()); 1275 __ cmp(result, factory()->the_hole_value());
1276 __ j(equal, &miss); 1276 __ j(equal, &miss);
1277 } else if (FLAG_debug_code) { 1277 } else if (FLAG_debug_code) {
1278 __ cmp(eax, factory()->the_hole_value()); 1278 __ cmp(result, factory()->the_hole_value());
1279 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 1279 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
1280 } 1280 }
1281 1281
1282 Counters* counters = isolate()->counters(); 1282 Counters* counters = isolate()->counters();
1283 __ IncrementCounter(counters->named_load_global_stub(), 1); 1283 __ IncrementCounter(counters->named_load_global_stub(), 1);
1284 // The code above already loads the result into the return register. 1284 // The code above already loads the result into the return register.
1285 __ ret(0); 1285 __ ret(0);
1286 1286
1287 FrontendFooter(name, &miss); 1287 FrontendFooter(name, &miss);
1288 1288
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 // ----------------------------------- 1388 // -----------------------------------
1389 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1389 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1390 } 1390 }
1391 1391
1392 1392
1393 #undef __ 1393 #undef __
1394 1394
1395 } } // namespace v8::internal 1395 } } // namespace v8::internal
1396 1396
1397 #endif // V8_TARGET_ARCH_IA32 1397 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm64/stub-cache-arm64.cc ('k') | src/ic.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698