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

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

Issue 12340112: Polymorphism support for load IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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 // 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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 370
371 371
372 // Load a fast property out of a holder object (src). In-object properties 372 // Load a fast property out of a holder object (src). In-object properties
373 // are loaded directly otherwise the property is loaded from the properties 373 // are loaded directly otherwise the property is loaded from the properties
374 // fixed array. 374 // fixed array.
375 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 375 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
376 Register dst, 376 Register dst,
377 Register src, 377 Register src,
378 Handle<JSObject> holder, 378 Handle<JSObject> holder,
379 PropertyIndex index) { 379 PropertyIndex index) {
380 if (index.is_header_index()) { 380 DoGenerateFastPropertyLoad(
381 int offset = index.header_index() * kPointerSize; 381 masm, dst, src, index.is_inobject(holder), index.translate(holder));
382 __ mov(dst, FieldOperand(src, offset));
383 } else {
384 // Adjust for the number of properties stored in the holder.
385 int slot = index.field_index() - holder->map()->inobject_properties();
386 if (slot < 0) {
387 // Get the property straight out of the holder.
388 int offset = holder->map()->instance_size() + (slot * kPointerSize);
389 __ mov(dst, FieldOperand(src, offset));
390 } else {
391 // Calculate the offset into the properties array.
392 int offset = slot * kPointerSize + FixedArray::kHeaderSize;
393 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
394 __ mov(dst, FieldOperand(dst, offset));
395 }
396 }
397 } 382 }
398 383
399 384
385 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
386 Register dst,
387 Register src,
388 bool inobject,
389 int index) {
390 int offset = index * kPointerSize;
391 if (!inobject) {
392 // Calculate the offset into the properties array.
393 offset = offset + FixedArray::kHeaderSize;
394 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
395 src = dst;
396 }
397 __ mov(dst, FieldOperand(src, offset));
398 }
399
400
400 static void PushInterceptorArguments(MacroAssembler* masm, 401 static void PushInterceptorArguments(MacroAssembler* masm,
401 Register receiver, 402 Register receiver,
402 Register holder, 403 Register holder,
403 Register name, 404 Register name,
404 Handle<JSObject> holder_obj) { 405 Handle<JSObject> holder_obj) {
405 __ push(name); 406 __ push(name);
406 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 407 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
407 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); 408 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
408 Register scratch = name; 409 Register scratch = name;
409 __ mov(scratch, Immediate(interceptor)); 410 __ mov(scratch, Immediate(interceptor));
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 938
938 939
939 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 940 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
940 Register object_reg, 941 Register object_reg,
941 Handle<JSObject> holder, 942 Handle<JSObject> holder,
942 Register holder_reg, 943 Register holder_reg,
943 Register scratch1, 944 Register scratch1,
944 Register scratch2, 945 Register scratch2,
945 Handle<String> name, 946 Handle<String> name,
946 int save_at_depth, 947 int save_at_depth,
947 Label* miss) { 948 Label* miss,
949 PrototypeCheckType check) {
950 Handle<JSObject> first = object;
948 // Make sure there's no overlap between holder and object registers. 951 // Make sure there's no overlap between holder and object registers.
949 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 952 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
950 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 953 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
951 && !scratch2.is(scratch1)); 954 && !scratch2.is(scratch1));
952 955
953 // Keep track of the current object in register reg. 956 // Keep track of the current object in register reg.
954 Register reg = object_reg; 957 Register reg = object_reg;
955 Handle<JSObject> current = object; 958 Handle<JSObject> current = object;
956 int depth = 0; 959 int depth = 0;
957 960
(...skipping 26 matching lines...) Expand all
984 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 987 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
985 reg = holder_reg; // From now on the object will be in holder_reg. 988 reg = holder_reg; // From now on the object will be in holder_reg.
986 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 989 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
987 } else { 990 } else {
988 bool in_new_space = heap()->InNewSpace(*prototype); 991 bool in_new_space = heap()->InNewSpace(*prototype);
989 Handle<Map> current_map(current->map()); 992 Handle<Map> current_map(current->map());
990 if (in_new_space) { 993 if (in_new_space) {
991 // Save the map in scratch1 for later. 994 // Save the map in scratch1 for later.
992 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 995 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
993 } 996 }
994 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK, 997 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) {
995 ALLOW_ELEMENT_TRANSITION_MAPS); 998 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK,
999 ALLOW_ELEMENT_TRANSITION_MAPS);
1000 }
996 1001
997 // Check access rights to the global object. This has to happen after 1002 // Check access rights to the global object. This has to happen after
998 // the map check so that we know that the object is actually a global 1003 // the map check so that we know that the object is actually a global
999 // object. 1004 // object.
1000 if (current->IsJSGlobalProxy()) { 1005 if (current->IsJSGlobalProxy()) {
1001 __ CheckAccessGlobalProxy(reg, scratch2, miss); 1006 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1002 } 1007 }
1003 reg = holder_reg; // From now on the object will be in holder_reg. 1008 reg = holder_reg; // From now on the object will be in holder_reg.
1004 1009
1005 if (in_new_space) { 1010 if (in_new_space) {
(...skipping 11 matching lines...) Expand all
1017 } 1022 }
1018 1023
1019 // Go to the next object in the prototype chain. 1024 // Go to the next object in the prototype chain.
1020 current = prototype; 1025 current = prototype;
1021 } 1026 }
1022 ASSERT(current.is_identical_to(holder)); 1027 ASSERT(current.is_identical_to(holder));
1023 1028
1024 // Log the check depth. 1029 // Log the check depth.
1025 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1030 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1026 1031
1027 // Check the holder map. 1032 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) {
1028 __ CheckMap(reg, Handle<Map>(holder->map()), 1033 // Check the holder map.
1029 miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); 1034 __ CheckMap(reg, Handle<Map>(holder->map()),
1035 miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
1036 }
1030 1037
1031 // Perform security check for access to the global object. 1038 // Perform security check for access to the global object.
1032 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1039 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1033 if (holder->IsJSGlobalProxy()) { 1040 if (holder->IsJSGlobalProxy()) {
1034 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1041 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1035 } 1042 }
1036 1043
1037 // If we've skipped any global objects, it's not enough to verify that 1044 // If we've skipped any global objects, it's not enough to verify that
1038 // their maps haven't changed. We also need to check that the property 1045 // their maps haven't changed. We also need to check that the property
1039 // cell for the property is still empty. 1046 // cell for the property is still empty.
1040 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1047 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1041 1048
1042 // Return the register containing the holder. 1049 // Return the register containing the holder.
1043 return reg; 1050 return reg;
1044 } 1051 }
1045 1052
1046 1053
1047 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1054 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success,
1048 Label* miss) { 1055 Label* miss) {
1049 __ jmp(success); 1056 if (!miss->is_unused()) {
1050 __ bind(miss); 1057 __ jmp(success);
1051 GenerateLoadMiss(masm(), kind()); 1058 __ bind(miss);
1059 GenerateLoadMiss(masm(), kind());
1060 }
1052 } 1061 }
1053 1062
1054 1063
1055 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1064 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1056 Handle<JSObject> object, 1065 Handle<JSObject> object,
1057 Register object_reg, 1066 Register object_reg,
1058 Handle<JSObject> holder, 1067 Handle<JSObject> holder,
1059 Handle<String> name, 1068 Handle<String> name,
1060 Label* success, 1069 Label* success,
1061 FrontendCheckType check,
1062 Handle<ExecutableAccessorInfo> callback) { 1070 Handle<ExecutableAccessorInfo> callback) {
1063 Label miss; 1071 Label miss;
1064 1072
1065 Register reg = HandlerFrontendHeader( 1073 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1066 object, object_reg, holder, name, &miss, check);
1067 1074
1068 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1075 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1069 ASSERT(!reg.is(scratch2())); 1076 ASSERT(!reg.is(scratch2()));
1070 ASSERT(!reg.is(scratch3())); 1077 ASSERT(!reg.is(scratch3()));
1071 Register dictionary = scratch1(); 1078 Register dictionary = scratch1();
1072 bool must_preserve_dictionary_reg = reg.is(dictionary); 1079 bool must_preserve_dictionary_reg = reg.is(dictionary);
1073 1080
1074 // Load the properties dictionary. 1081 // Load the properties dictionary.
1075 if (must_preserve_dictionary_reg) { 1082 if (must_preserve_dictionary_reg) {
1076 __ push(dictionary); 1083 __ push(dictionary);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 1122
1116 1123
1117 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1124 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1118 Handle<JSObject> object, 1125 Handle<JSObject> object,
1119 Handle<JSObject> last, 1126 Handle<JSObject> last,
1120 Handle<String> name, 1127 Handle<String> name,
1121 Label* success, 1128 Label* success,
1122 Handle<GlobalObject> global) { 1129 Handle<GlobalObject> global) {
1123 Label miss; 1130 Label miss;
1124 1131
1125 Register reg = HandlerFrontendHeader( 1132 Register reg = HandlerFrontendHeader(object, receiver(), last, name, &miss);
1126 object, receiver(), last, name, &miss, PERFORM_INITIAL_CHECKS);
1127 1133
1128 // If the last object in the prototype chain is a global object, 1134 // If the last object in the prototype chain is a global object,
1129 // check that the global property cell is empty. 1135 // check that the global property cell is empty.
1130 if (!global.is_null()) { 1136 if (!global.is_null()) {
1131 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1137 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1132 } 1138 }
1133 1139
1134 if (!last->HasFastProperties()) { 1140 if (!last->HasFastProperties()) {
1135 __ mov(scratch2(), FieldOperand(reg, HeapObject::kMapOffset)); 1141 __ mov(scratch2(), FieldOperand(reg, HeapObject::kMapOffset));
1136 __ mov(scratch2(), FieldOperand(scratch2(), Map::kPrototypeOffset)); 1142 __ mov(scratch2(), FieldOperand(scratch2(), Map::kPrototypeOffset));
(...skipping 18 matching lines...) Expand all
1155 Register reg, 1161 Register reg,
1156 Handle<ExecutableAccessorInfo> callback) { 1162 Handle<ExecutableAccessorInfo> callback) {
1157 // Insert additional parameters into the stack frame above return address. 1163 // Insert additional parameters into the stack frame above return address.
1158 ASSERT(!scratch3().is(reg)); 1164 ASSERT(!scratch3().is(reg));
1159 __ pop(scratch3()); // Get return address to place it below. 1165 __ pop(scratch3()); // Get return address to place it below.
1160 1166
1161 __ push(receiver()); // receiver 1167 __ push(receiver()); // receiver
1162 __ mov(scratch2(), esp); 1168 __ mov(scratch2(), esp);
1163 ASSERT(!scratch2().is(reg)); 1169 ASSERT(!scratch2().is(reg));
1164 __ push(reg); // holder 1170 __ push(reg); // holder
1165 // Push data from AccessorInfo. 1171 // Push data from ExecutableAccessorInfo.
1166 if (isolate()->heap()->InNewSpace(callback->data())) { 1172 if (isolate()->heap()->InNewSpace(callback->data())) {
1167 __ mov(scratch1(), Immediate(callback)); 1173 __ mov(scratch1(), Immediate(callback));
1168 __ push(FieldOperand(scratch1(), ExecutableAccessorInfo::kDataOffset)); 1174 __ push(FieldOperand(scratch1(), ExecutableAccessorInfo::kDataOffset));
1169 } else { 1175 } else {
1170 __ push(Immediate(Handle<Object>(callback->data(), isolate()))); 1176 __ push(Immediate(Handle<Object>(callback->data(), isolate())));
1171 } 1177 }
1172 __ push(Immediate(reinterpret_cast<int>(isolate()))); 1178 __ push(Immediate(reinterpret_cast<int>(isolate())));
1173 1179
1174 // Save a pointer to where we pushed the arguments pointer. 1180 // Save a pointer to where we pushed the arguments pointer. This will be
1175 // This will be passed as the const AccessorInfo& to the C++ callback. 1181 // passed as the const ExecutableAccessorInfo& to the C++ callback.
1176 __ push(scratch2()); 1182 __ push(scratch2());
1177 1183
1178 __ push(name()); // name 1184 __ push(name()); // name
1179 __ mov(ebx, esp); // esp points to reference to name (handler). 1185 __ mov(ebx, esp); // esp points to reference to name (handler).
1180 1186
1181 __ push(scratch3()); // Restore return address. 1187 __ push(scratch3()); // Restore return address.
1182 1188
1183 // 4 elements array for v8::Arguments::values_, handler for name and pointer 1189 // 4 elements array for v8::Arguments::values_, handler for name and pointer
1184 // to the values (it considered as smi in GC). 1190 // to the values (it considered as smi in GC).
1185 const int kStackSpace = 6; 1191 const int kStackSpace = 6;
(...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 2926
2921 NonexistentHandlerFrontend(object, last, name, &success, global); 2927 NonexistentHandlerFrontend(object, last, name, &success, global);
2922 2928
2923 __ bind(&success); 2929 __ bind(&success);
2924 // Return undefined if maps of the full prototype chain are still the 2930 // Return undefined if maps of the full prototype chain are still the
2925 // same and no global property with this name contains a value. 2931 // same and no global property with this name contains a value.
2926 __ mov(eax, isolate()->factory()->undefined_value()); 2932 __ mov(eax, isolate()->factory()->undefined_value());
2927 __ ret(0); 2933 __ ret(0);
2928 2934
2929 // Return the generated code. 2935 // Return the generated code.
2930 return GetCode(Code::NONEXISTENT, factory()->empty_string()); 2936 return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name);
2931 } 2937 }
2932 2938
2933 2939
2934 Register* LoadStubCompiler::registers() { 2940 Register* LoadStubCompiler::registers() {
2935 // receiver, name, scratch1, scratch2, scratch3, scratch4. 2941 // receiver, name, scratch1, scratch2, scratch3, scratch4.
2936 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg }; 2942 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
2937 return registers; 2943 return registers;
2938 } 2944 }
2939 2945
2940 2946
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 2997
2992 2998
2993 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 2999 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
2994 Handle<JSObject> object, 3000 Handle<JSObject> object,
2995 Handle<GlobalObject> global, 3001 Handle<GlobalObject> global,
2996 Handle<JSGlobalPropertyCell> cell, 3002 Handle<JSGlobalPropertyCell> cell,
2997 Handle<String> name, 3003 Handle<String> name,
2998 bool is_dont_delete) { 3004 bool is_dont_delete) {
2999 Label success, miss; 3005 Label success, miss;
3000 3006
3001 HandlerFrontendHeader(object, receiver(), Handle<JSObject>::cast(global), 3007 __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
3002 name, &miss, PERFORM_INITIAL_CHECKS); 3008 HandlerFrontendHeader(
3009 object, receiver(), Handle<JSObject>::cast(global), name, &miss);
3003 // Get the value from the cell. 3010 // Get the value from the cell.
3004 if (Serializer::enabled()) { 3011 if (Serializer::enabled()) {
3005 __ mov(eax, Immediate(cell)); 3012 __ mov(eax, Immediate(cell));
3006 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); 3013 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset));
3007 } else { 3014 } else {
3008 __ mov(eax, Operand::Cell(cell)); 3015 __ mov(eax, Operand::Cell(cell));
3009 } 3016 }
3010 3017
3011 // Check for deleted property if property can actually be deleted. 3018 // Check for deleted property if property can actually be deleted.
3012 if (!is_dont_delete) { 3019 if (!is_dont_delete) {
3013 __ cmp(eax, factory()->the_hole_value()); 3020 __ cmp(eax, factory()->the_hole_value());
3014 __ j(equal, &miss); 3021 __ j(equal, &miss);
3015 } else if (FLAG_debug_code) { 3022 } else if (FLAG_debug_code) {
3016 __ cmp(eax, factory()->the_hole_value()); 3023 __ cmp(eax, factory()->the_hole_value());
3017 __ Check(not_equal, "DontDelete cells can't contain the hole"); 3024 __ Check(not_equal, "DontDelete cells can't contain the hole");
3018 } 3025 }
3019 3026
3020 HandlerFrontendFooter(&success, &miss); 3027 HandlerFrontendFooter(&success, &miss);
3021 __ bind(&success); 3028 __ bind(&success);
3022 3029
3023 Counters* counters = isolate()->counters(); 3030 Counters* counters = isolate()->counters();
3024 __ IncrementCounter(counters->named_load_global_stub(), 1); 3031 __ IncrementCounter(counters->named_load_global_stub(), 1);
3025 // The code above already loads the result into the return register. 3032 // The code above already loads the result into the return register.
3026 __ ret(0); 3033 __ ret(0);
3027 3034
3028 // Return the generated code. 3035 // Return the generated code.
3029 return GetCode(Code::NORMAL, name); 3036 return GetCode(Code::IC_FRAGMENT, Code::NORMAL, name);
3030 } 3037 }
3031 3038
3032 3039
3033 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 3040 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
3034 Handle<Map> receiver_map) { 3041 Handle<Map> receiver_map) {
3035 // ----------- S t a t e ------------- 3042 // ----------- S t a t e -------------
3036 // -- ecx : key 3043 // -- ecx : key
3037 // -- edx : receiver 3044 // -- edx : receiver
3038 // -- esp[0] : return address 3045 // -- esp[0] : return address
3039 // ----------------------------------- 3046 // -----------------------------------
3040 3047
3041 ElementsKind elements_kind = receiver_map->elements_kind(); 3048 ElementsKind elements_kind = receiver_map->elements_kind();
3042 if (receiver_map->has_fast_elements() || 3049 if (receiver_map->has_fast_elements() ||
3043 receiver_map->has_external_array_elements()) { 3050 receiver_map->has_external_array_elements()) {
3044 Handle<Code> stub = KeyedLoadFastElementStub( 3051 Handle<Code> stub = KeyedLoadFastElementStub(
3045 receiver_map->instance_type() == JS_ARRAY_TYPE, 3052 receiver_map->instance_type() == JS_ARRAY_TYPE,
3046 elements_kind).GetCode(isolate()); 3053 elements_kind).GetCode(isolate());
3047 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); 3054 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
3048 } else { 3055 } else {
3049 Handle<Code> stub = 3056 Handle<Code> stub =
3050 KeyedLoadDictionaryElementStub().GetCode(isolate()); 3057 KeyedLoadDictionaryElementStub().GetCode(isolate());
3051 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); 3058 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
3052 } 3059 }
3053 3060
3054 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3061 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3055 3062
3056 // Return the generated code. 3063 // Return the generated code.
3057 return GetCode(Code::NORMAL, factory()->empty_string()); 3064 return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string());
3058 } 3065 }
3059 3066
3060 3067
3061 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( 3068 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
3062 MapHandleList* receiver_maps, 3069 MapHandleList* receiver_maps,
3063 CodeHandleList* handler_ics) { 3070 CodeHandleList* handlers,
3064 // ----------- S t a t e ------------- 3071 Handle<String> name,
3065 // -- ecx : key 3072 Code::StubType type,
3066 // -- edx : receiver 3073 IcCheckType check) {
3067 // -- esp[0] : return address
3068 // -----------------------------------
3069 Label miss; 3074 Label miss;
3070 __ JumpIfSmi(edx, &miss);
3071 3075
3072 Register map_reg = ebx; 3076 if (check == PROPERTY) {
3073 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); 3077 GenerateNameCheck(name, this->name(), &miss);
3078 }
3079
3080 __ JumpIfSmi(receiver(), &miss);
3081 Register map_reg = scratch1();
3082 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
3074 int receiver_count = receiver_maps->length(); 3083 int receiver_count = receiver_maps->length();
3075 for (int current = 0; current < receiver_count; ++current) { 3084 for (int current = 0; current < receiver_count; ++current) {
3076 __ cmp(map_reg, receiver_maps->at(current)); 3085 __ cmp(map_reg, receiver_maps->at(current));
3077 __ j(equal, handler_ics->at(current)); 3086 __ j(equal, handlers->at(current));
3078 } 3087 }
3079 3088
3080 __ bind(&miss); 3089 __ bind(&miss);
3081 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3090 GenerateLoadMiss(masm(), kind());
3082 3091
3083 // Return the generated code. 3092 // Return the generated code.
3084 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3093 InlineCacheState state =
3094 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
3095 return GetCode(Code::IC_FRAGMENT, type, name, state);
3085 } 3096 }
3086 3097
3087 3098
3088 // Specialized stub for constructing objects from functions which only have only 3099 // Specialized stub for constructing objects from functions which only have only
3089 // simple assignments of the form this.x = ...; in their body. 3100 // simple assignments of the form this.x = ...; in their body.
3090 Handle<Code> ConstructStubCompiler::CompileConstructStub( 3101 Handle<Code> ConstructStubCompiler::CompileConstructStub(
3091 Handle<JSFunction> function) { 3102 Handle<JSFunction> function) {
3092 // ----------- S t a t e ------------- 3103 // ----------- S t a t e -------------
3093 // -- eax : argc 3104 // -- eax : argc
3094 // -- edi : constructor 3105 // -- edi : constructor
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
3802 __ jmp(ic_slow, RelocInfo::CODE_TARGET); 3813 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3803 } 3814 }
3804 } 3815 }
3805 3816
3806 3817
3807 #undef __ 3818 #undef __
3808 3819
3809 } } // namespace v8::internal 3820 } } // namespace v8::internal
3810 3821
3811 #endif // V8_TARGET_ARCH_IA32 3822 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698