| OLD | NEW |
| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 kind, extra_state, cache_holder); | 109 kind, extra_state, cache_holder); |
| 110 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); | 110 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); |
| 111 if (probe->IsCode()) return Handle<Code>::cast(probe); | 111 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 112 return Handle<Code>::null(); | 112 return Handle<Code>::null(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 116 Handle<Code> StubCache::FindHandler(Handle<Name> name, |
| 117 Handle<Map> stub_holder, | 117 Handle<Map> stub_holder, |
| 118 Code::Kind kind, | 118 Code::Kind kind, |
| 119 InlineCacheHolderFlag cache_holder, | 119 InlineCacheHolderFlag cache_holder) { |
| 120 Code::StubType type) { | 120 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 121 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); | 121 Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind); |
| 122 | 122 |
| 123 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); | 123 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); |
| 124 if (probe->IsCode()) return Handle<Code>::cast(probe); | 124 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 125 return Handle<Code>::null(); | 125 return Handle<Code>::null(); |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 Handle<Code> StubCache::ComputeMonomorphicIC( | 129 Handle<Code> StubCache::ComputeMonomorphicIC( |
| 130 Code::Kind kind, | |
| 131 Handle<Name> name, | 130 Handle<Name> name, |
| 132 Handle<HeapType> type, | 131 Handle<HeapType> type, |
| 133 Handle<Code> handler, | 132 Handle<Code> handler, |
| 134 ExtraICState extra_ic_state) { | 133 ExtraICState extra_ic_state) { |
| 134 Code::Kind kind = handler->handler_kind(); |
| 135 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); | 135 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); |
| 136 | 136 |
| 137 Handle<Map> stub_holder; | 137 Handle<Map> stub_holder; |
| 138 Handle<Code> ic; | 138 Handle<Code> ic; |
| 139 // There are multiple string maps that all use the same prototype. That | 139 // There are multiple string maps that all use the same prototype. That |
| 140 // prototype cannot hold multiple handlers, one for each of the string maps, | 140 // prototype cannot hold multiple handlers, one for each of the string maps, |
| 141 // for a single name. Hence, turn off caching of the IC. | 141 // for a single name. Hence, turn off caching of the IC. |
| 142 bool can_be_cached = !type->Is(HeapType::String()); | 142 bool can_be_cached = !type->Is(HeapType::String()); |
| 143 if (can_be_cached) { | 143 if (can_be_cached) { |
| 144 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); | 144 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 while (!next->IsNull()) { | 185 while (!next->IsNull()) { |
| 186 last = Handle<JSObject>::cast(next); | 186 last = Handle<JSObject>::cast(next); |
| 187 next = handle(current_map->prototype(), isolate()); | 187 next = handle(current_map->prototype(), isolate()); |
| 188 current_map = handle(Handle<HeapObject>::cast(next)->map()); | 188 current_map = handle(Handle<HeapObject>::cast(next)->map()); |
| 189 if (current_map->is_dictionary_map()) cache_name = name; | 189 if (current_map->is_dictionary_map()) cache_name = name; |
| 190 } | 190 } |
| 191 | 191 |
| 192 // Compile the stub that is either shared for all names or | 192 // Compile the stub that is either shared for all names or |
| 193 // name specific if there are global objects involved. | 193 // name specific if there are global objects involved. |
| 194 Handle<Code> handler = FindHandler( | 194 Handle<Code> handler = FindHandler( |
| 195 cache_name, stub_holder, Code::LOAD_IC, flag, Code::FAST); | 195 cache_name, stub_holder, Code::LOAD_IC, flag); |
| 196 if (!handler.is_null()) { | 196 if (!handler.is_null()) return handler; |
| 197 return handler; | |
| 198 } | |
| 199 | 197 |
| 200 LoadStubCompiler compiler(isolate_, kNoExtraICState, flag); | 198 LoadStubCompiler compiler(isolate_, kNoExtraICState, flag); |
| 201 handler = compiler.CompileLoadNonexistent(type, last, cache_name); | 199 handler = compiler.CompileLoadNonexistent(type, last, cache_name); |
| 202 Map::UpdateCodeCache(stub_holder, cache_name, handler); | 200 Map::UpdateCodeCache(stub_holder, cache_name, handler); |
| 203 return handler; | 201 return handler; |
| 204 } | 202 } |
| 205 | 203 |
| 206 | 204 |
| 207 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 205 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
| 208 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); | 362 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); |
| 365 | 363 |
| 366 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 364 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
| 367 | 365 |
| 368 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 366 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 369 return code; | 367 return code; |
| 370 } | 368 } |
| 371 | 369 |
| 372 | 370 |
| 373 Handle<Code> StubCache::ComputePolymorphicIC( | 371 Handle<Code> StubCache::ComputePolymorphicIC( |
| 374 Code::Kind kind, | |
| 375 TypeHandleList* types, | 372 TypeHandleList* types, |
| 376 CodeHandleList* handlers, | 373 CodeHandleList* handlers, |
| 377 int number_of_valid_types, | 374 int number_of_valid_types, |
| 378 Handle<Name> name, | 375 Handle<Name> name, |
| 379 ExtraICState extra_ic_state) { | 376 ExtraICState extra_ic_state) { |
| 377 |
| 380 Handle<Code> handler = handlers->at(0); | 378 Handle<Code> handler = handlers->at(0); |
| 379 Code::Kind kind = handler->handler_kind(); |
| 381 Code::StubType type = number_of_valid_types == 1 ? handler->type() | 380 Code::StubType type = number_of_valid_types == 1 ? handler->type() |
| 382 : Code::NORMAL; | 381 : Code::NORMAL; |
| 383 if (kind == Code::LOAD_IC) { | 382 if (kind == Code::LOAD_IC) { |
| 384 LoadStubCompiler ic_compiler(isolate_, extra_ic_state); | 383 LoadStubCompiler ic_compiler(isolate_, extra_ic_state); |
| 385 return ic_compiler.CompilePolymorphicIC( | 384 return ic_compiler.CompilePolymorphicIC( |
| 386 types, handlers, name, type, PROPERTY); | 385 types, handlers, name, type, PROPERTY); |
| 387 } else { | 386 } else { |
| 388 ASSERT(kind == Code::STORE_IC); | 387 ASSERT(kind == Code::STORE_IC); |
| 389 StoreStubCompiler ic_compiler(isolate_, extra_ic_state); | 388 StoreStubCompiler ic_compiler(isolate_, extra_ic_state); |
| 390 return ic_compiler.CompilePolymorphicIC( | 389 return ic_compiler.CompilePolymorphicIC( |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 LoadIC::GeneratePreMonomorphic(masm()); | 683 LoadIC::GeneratePreMonomorphic(masm()); |
| 685 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); | 684 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); |
| 686 PROFILE(isolate(), | 685 PROFILE(isolate(), |
| 687 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); | 686 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); |
| 688 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); | 687 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); |
| 689 return code; | 688 return code; |
| 690 } | 689 } |
| 691 | 690 |
| 692 | 691 |
| 693 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) { | 692 Handle<Code> StubCompiler::CompileLoadMegamorphic(Code::Flags flags) { |
| 694 LoadIC::GenerateMegamorphic(masm()); | 693 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 694 ContextualMode mode = LoadIC::GetContextualMode(extra_state); |
| 695 LoadIC::GenerateMegamorphic(masm(), mode); |
| 695 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); | 696 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); |
| 696 PROFILE(isolate(), | 697 PROFILE(isolate(), |
| 697 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0)); | 698 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0)); |
| 698 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); | 699 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); |
| 699 return code; | 700 return code; |
| 700 } | 701 } |
| 701 | 702 |
| 702 | 703 |
| 703 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) { | 704 Handle<Code> StubCompiler::CompileStoreInitialize(Code::Flags flags) { |
| 704 StoreIC::GenerateInitialize(masm()); | 705 StoreIC::GenerateInitialize(masm()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 726 StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode); | 727 StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode); |
| 727 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric"); | 728 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric"); |
| 728 PROFILE(isolate(), | 729 PROFILE(isolate(), |
| 729 CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0)); | 730 CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0)); |
| 730 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *code)); | 731 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *code)); |
| 731 return code; | 732 return code; |
| 732 } | 733 } |
| 733 | 734 |
| 734 | 735 |
| 735 Handle<Code> StubCompiler::CompileStoreMegamorphic(Code::Flags flags) { | 736 Handle<Code> StubCompiler::CompileStoreMegamorphic(Code::Flags flags) { |
| 736 StoreIC::GenerateMegamorphic(masm()); | 737 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 738 StoreIC::GenerateMegamorphic(masm(), extra_state); |
| 737 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); | 739 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); |
| 738 PROFILE(isolate(), | 740 PROFILE(isolate(), |
| 739 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); | 741 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); |
| 740 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *code)); | 742 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *code)); |
| 741 return code; | 743 return code; |
| 742 } | 744 } |
| 743 | 745 |
| 744 | 746 |
| 745 #undef CALL_LOGGER_TAG | 747 #undef CALL_LOGGER_TAG |
| 746 | 748 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 | 944 |
| 943 | 945 |
| 944 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 946 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
| 945 Handle<HeapType> type, | 947 Handle<HeapType> type, |
| 946 Handle<JSObject> holder, | 948 Handle<JSObject> holder, |
| 947 Handle<Name> name, | 949 Handle<Name> name, |
| 948 const CallOptimization& call_optimization) { | 950 const CallOptimization& call_optimization) { |
| 949 ASSERT(call_optimization.is_simple_api_call()); | 951 ASSERT(call_optimization.is_simple_api_call()); |
| 950 Handle<JSFunction> callback = call_optimization.constant_function(); | 952 Handle<JSFunction> callback = call_optimization.constant_function(); |
| 951 CallbackHandlerFrontend(type, receiver(), holder, name, callback); | 953 CallbackHandlerFrontend(type, receiver(), holder, name, callback); |
| 952 Handle<Map>receiver_map = IC::TypeToMap(*type, isolate()); | 954 GenerateLoadCallback(call_optimization, IC::TypeToMap(*type, isolate())); |
| 953 GenerateFastApiCall( | 955 |
| 954 masm(), call_optimization, receiver_map, | |
| 955 receiver(), scratch1(), false, 0, NULL); | |
| 956 // Return the generated code. | 956 // Return the generated code. |
| 957 return GetCode(kind(), Code::FAST, name); | 957 return GetCode(kind(), Code::FAST, name); |
| 958 } | 958 } |
| 959 | 959 |
| 960 | 960 |
| 961 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( | 961 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( |
| 962 Handle<HeapType> type, | 962 Handle<HeapType> type, |
| 963 Handle<JSObject> holder, | 963 Handle<JSObject> holder, |
| 964 Handle<Name> name) { | 964 Handle<Name> name) { |
| 965 LookupResult lookup(isolate()); | 965 LookupResult lookup(isolate()); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 Handle<Name> name, | 1124 Handle<Name> name, |
| 1125 Handle<JSFunction> setter) { | 1125 Handle<JSFunction> setter) { |
| 1126 Handle<HeapType> type = IC::CurrentTypeOf(object, isolate()); | 1126 Handle<HeapType> type = IC::CurrentTypeOf(object, isolate()); |
| 1127 HandlerFrontend(type, receiver(), holder, name); | 1127 HandlerFrontend(type, receiver(), holder, name); |
| 1128 GenerateStoreViaSetter(masm(), type, setter); | 1128 GenerateStoreViaSetter(masm(), type, setter); |
| 1129 | 1129 |
| 1130 return GetCode(kind(), Code::FAST, name); | 1130 return GetCode(kind(), Code::FAST, name); |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 | 1133 |
| 1134 Handle<Code> StoreStubCompiler::CompileStoreCallback( | |
| 1135 Handle<JSObject> object, | |
| 1136 Handle<JSObject> holder, | |
| 1137 Handle<Name> name, | |
| 1138 const CallOptimization& call_optimization) { | |
| 1139 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), | |
| 1140 receiver(), holder, name); | |
| 1141 Register values[] = { value() }; | |
| 1142 GenerateFastApiCall( | |
| 1143 masm(), call_optimization, handle(object->map()), | |
| 1144 receiver(), scratch1(), true, 1, values); | |
| 1145 // Return the generated code. | |
| 1146 return GetCode(kind(), Code::FAST, name); | |
| 1147 } | |
| 1148 | |
| 1149 | |
| 1150 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 1134 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
| 1151 Handle<Map> receiver_map) { | 1135 Handle<Map> receiver_map) { |
| 1152 ElementsKind elements_kind = receiver_map->elements_kind(); | 1136 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 1153 if (receiver_map->has_fast_elements() || | 1137 if (receiver_map->has_fast_elements() || |
| 1154 receiver_map->has_external_array_elements() || | 1138 receiver_map->has_external_array_elements() || |
| 1155 receiver_map->has_fixed_typed_array_elements()) { | 1139 receiver_map->has_fixed_typed_array_elements()) { |
| 1156 Handle<Code> stub = KeyedLoadFastElementStub( | 1140 Handle<Code> stub = KeyedLoadFastElementStub( |
| 1157 receiver_map->instance_type() == JS_ARRAY_TYPE, | 1141 receiver_map->instance_type() == JS_ARRAY_TYPE, |
| 1158 elements_kind).GetCode(isolate()); | 1142 elements_kind).GetCode(isolate()); |
| 1159 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); | 1143 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1245 Handle<Code> code = GetCodeWithFlags(flags, name); | 1229 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1246 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1230 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
| 1247 JitEvent(name, code); | 1231 JitEvent(name, code); |
| 1248 return code; | 1232 return code; |
| 1249 } | 1233 } |
| 1250 | 1234 |
| 1251 | 1235 |
| 1252 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, | 1236 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, |
| 1253 Code::StubType type, | 1237 Code::StubType type, |
| 1254 Handle<Name> name) { | 1238 Handle<Name> name) { |
| 1255 ASSERT_EQ(kNoExtraICState, extra_state()); | 1239 Code::Flags flags = Code::ComputeFlags( |
| 1256 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder_); | 1240 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind, cache_holder_); |
| 1257 Handle<Code> code = GetCodeWithFlags(flags, name); | 1241 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1258 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1242 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
| 1259 JitEvent(name, code); | 1243 JitEvent(name, code); |
| 1260 return code; | 1244 return code; |
| 1261 } | 1245 } |
| 1262 | 1246 |
| 1263 | 1247 |
| 1264 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, | 1248 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, |
| 1265 CodeHandleList* handlers) { | 1249 CodeHandleList* handlers) { |
| 1266 for (int i = 0; i < receiver_maps->length(); ++i) { | 1250 for (int i = 0; i < receiver_maps->length(); ++i) { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 Handle<FunctionTemplateInfo>( | 1446 Handle<FunctionTemplateInfo>( |
| 1463 FunctionTemplateInfo::cast(signature->receiver())); | 1447 FunctionTemplateInfo::cast(signature->receiver())); |
| 1464 } | 1448 } |
| 1465 } | 1449 } |
| 1466 | 1450 |
| 1467 is_simple_api_call_ = true; | 1451 is_simple_api_call_ = true; |
| 1468 } | 1452 } |
| 1469 | 1453 |
| 1470 | 1454 |
| 1471 } } // namespace v8::internal | 1455 } } // namespace v8::internal |
| OLD | NEW |