Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/ast.h" | 9 #include "src/ast.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 Handle<Code> ic; | 136 Handle<Code> ic; |
| 137 // There are multiple string maps that all use the same prototype. That | 137 // There are multiple string maps that all use the same prototype. That |
| 138 // prototype cannot hold multiple handlers, one for each of the string maps, | 138 // prototype cannot hold multiple handlers, one for each of the string maps, |
| 139 // for a single name. Hence, turn off caching of the IC. | 139 // for a single name. Hence, turn off caching of the IC. |
| 140 bool can_be_cached = !type->Is(HeapType::String()); | 140 bool can_be_cached = !type->Is(HeapType::String()); |
| 141 if (can_be_cached) { | 141 if (can_be_cached) { |
| 142 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag); | 142 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag); |
| 143 if (!ic.is_null()) return ic; | 143 if (!ic.is_null()) return ic; |
| 144 } | 144 } |
| 145 | 145 |
| 146 if (kind == Code::LOAD_IC) { | 146 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) { |
| 147 LoadStubCompiler ic_compiler(isolate(), extra_ic_state, flag); | 147 LoadStubCompiler ic_compiler(isolate(), kind, extra_ic_state, flag); |
| 148 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | |
| 149 } else if (kind == Code::KEYED_LOAD_IC) { | |
| 150 KeyedLoadStubCompiler ic_compiler(isolate(), extra_ic_state, flag); | |
| 151 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 148 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 152 } else if (kind == Code::STORE_IC) { | 149 } else if (kind == Code::STORE_IC) { |
| 153 StoreStubCompiler ic_compiler(isolate(), extra_ic_state); | 150 StoreStubCompiler ic_compiler(isolate(), extra_ic_state); |
| 154 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 151 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 155 } else { | 152 } else { |
| 156 ASSERT(kind == Code::KEYED_STORE_IC); | 153 ASSERT(kind == Code::KEYED_STORE_IC); |
| 157 ASSERT(STANDARD_STORE == | 154 ASSERT(STANDARD_STORE == |
| 158 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); | 155 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); |
| 159 KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state); | 156 KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state); |
| 160 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 190 Handle<Map> current_map = stub_holder_map; | 187 Handle<Map> current_map = stub_holder_map; |
| 191 Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); | 188 Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); |
| 192 while (true) { | 189 while (true) { |
| 193 if (current_map->is_dictionary_map()) cache_name = name; | 190 if (current_map->is_dictionary_map()) cache_name = name; |
| 194 if (current_map->prototype()->IsNull()) break; | 191 if (current_map->prototype()->IsNull()) break; |
| 195 last = handle(JSObject::cast(current_map->prototype())); | 192 last = handle(JSObject::cast(current_map->prototype())); |
| 196 current_map = handle(last->map()); | 193 current_map = handle(last->map()); |
| 197 } | 194 } |
| 198 // Compile the stub that is either shared for all names or | 195 // Compile the stub that is either shared for all names or |
| 199 // name specific if there are global objects involved. | 196 // name specific if there are global objects involved. |
| 197 Code::Kind handler_kind = Code::LOAD_IC; | |
| 200 Handle<Code> handler = | 198 Handle<Code> handler = |
| 201 FindHandler(cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); | 199 FindHandler(cache_name, stub_holder_map, handler_kind, flag, Code::FAST); |
| 202 if (!handler.is_null()) { | 200 if (!handler.is_null()) { |
| 203 return handler; | 201 return handler; |
| 204 } | 202 } |
| 205 | 203 |
| 206 LoadStubCompiler compiler(isolate_, kNoExtraICState, flag); | 204 LoadStubCompiler compiler(isolate_, handler_kind, kNoExtraICState, flag); |
| 207 handler = compiler.CompileLoadNonexistent(type, last, cache_name); | 205 handler = compiler.CompileLoadNonexistent(type, last, cache_name); |
| 208 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); | 206 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); |
| 209 return handler; | 207 return handler; |
| 210 } | 208 } |
| 211 | 209 |
| 212 | 210 |
| 213 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 211 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
| 214 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 212 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
| 215 Handle<Name> name = | 213 Handle<Name> name = |
| 216 isolate()->factory()->KeyedLoadElementMonomorphic_string(); | 214 isolate()->factory()->KeyedLoadElementMonomorphic_string(); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 Handle<Object> probe = cache->Lookup(receiver_maps, flags); | 358 Handle<Object> probe = cache->Lookup(receiver_maps, flags); |
| 361 if (probe->IsCode()) return Handle<Code>::cast(probe); | 359 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 362 | 360 |
| 363 TypeHandleList types(receiver_maps->length()); | 361 TypeHandleList types(receiver_maps->length()); |
| 364 for (int i = 0; i < receiver_maps->length(); i++) { | 362 for (int i = 0; i < receiver_maps->length(); i++) { |
| 365 types.Add(HeapType::Class(receiver_maps->at(i), isolate())); | 363 types.Add(HeapType::Class(receiver_maps->at(i), isolate())); |
| 366 } | 364 } |
| 367 CodeHandleList handlers(receiver_maps->length()); | 365 CodeHandleList handlers(receiver_maps->length()); |
| 368 KeyedLoadStubCompiler compiler(isolate_); | 366 KeyedLoadStubCompiler compiler(isolate_); |
| 369 compiler.CompileElementHandlers(receiver_maps, &handlers); | 367 compiler.CompileElementHandlers(receiver_maps, &handlers); |
| 370 Handle<Code> code = compiler.CompilePolymorphicIC( | 368 LoadStubCompiler ic_compiler(isolate_, Code::KEYED_LOAD_IC); |
| 369 Handle<Code> code = ic_compiler.CompilePolymorphicIC( | |
| 371 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); | 370 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); |
| 372 | 371 |
| 373 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 372 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
| 374 | 373 |
| 375 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 374 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 376 return code; | 375 return code; |
| 377 } | 376 } |
| 378 | 377 |
| 379 | 378 |
| 380 Handle<Code> StubCache::ComputePolymorphicIC( | 379 Handle<Code> StubCache::ComputePolymorphicIC( |
| 381 Code::Kind kind, | 380 Code::Kind kind, |
| 382 TypeHandleList* types, | 381 TypeHandleList* types, |
| 383 CodeHandleList* handlers, | 382 CodeHandleList* handlers, |
| 384 int number_of_valid_types, | 383 int number_of_valid_types, |
| 385 Handle<Name> name, | 384 Handle<Name> name, |
| 386 ExtraICState extra_ic_state) { | 385 ExtraICState extra_ic_state) { |
| 387 Handle<Code> handler = handlers->at(0); | 386 Handle<Code> handler = handlers->at(0); |
| 388 Code::StubType type = number_of_valid_types == 1 ? handler->type() | 387 Code::StubType type = number_of_valid_types == 1 ? handler->type() |
| 389 : Code::NORMAL; | 388 : Code::NORMAL; |
| 390 if (kind == Code::LOAD_IC) { | 389 if (kind == Code::LOAD_IC) { |
| 391 LoadStubCompiler ic_compiler(isolate_, extra_ic_state); | 390 LoadStubCompiler ic_compiler(isolate_, kind, extra_ic_state); |
| 392 return ic_compiler.CompilePolymorphicIC( | 391 return ic_compiler.CompilePolymorphicIC( |
| 393 types, handlers, name, type, PROPERTY); | 392 types, handlers, name, type, PROPERTY); |
| 394 } else { | 393 } else { |
| 395 ASSERT(kind == Code::STORE_IC); | 394 ASSERT(kind == Code::STORE_IC); |
| 396 StoreStubCompiler ic_compiler(isolate_, extra_ic_state); | 395 StoreStubCompiler ic_compiler(isolate_, extra_ic_state); |
| 397 return ic_compiler.CompilePolymorphicIC( | 396 return ic_compiler.CompilePolymorphicIC( |
| 398 types, handlers, name, type, PROPERTY); | 397 types, handlers, name, type, PROPERTY); |
| 399 } | 398 } |
| 400 } | 399 } |
| 401 | 400 |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1137 } else { | 1136 } else { |
| 1138 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads | 1137 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads |
| 1139 ? KeyedLoadDictionaryElementStub(isolate()).GetCode() | 1138 ? KeyedLoadDictionaryElementStub(isolate()).GetCode() |
| 1140 : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode(); | 1139 : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode(); |
| 1141 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); | 1140 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); |
| 1142 } | 1141 } |
| 1143 | 1142 |
| 1144 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss); | 1143 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss); |
| 1145 | 1144 |
| 1146 // Return the generated code. | 1145 // Return the generated code. |
| 1147 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | 1146 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, MONOMORPHIC, |
|
mvstanton
2014/07/23 08:09:28
Why can't GetICCode() be used? Can it be moved in
Toon Verwaest
2014/07/23 10:28:42
I'll move this stuff together in another CL in an
| |
| 1147 extra_state(), Code::NORMAL); | |
| 1148 Handle<Code> code = GetCodeWithFlags(flags, factory()->empty_string()); | |
| 1149 IC::RegisterWeakMapDependency(code); | |
| 1150 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, | |
| 1151 heap()->empty_string())); | |
| 1152 return code; | |
| 1148 } | 1153 } |
| 1149 | 1154 |
| 1150 | 1155 |
| 1151 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( | 1156 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( |
| 1152 Handle<Map> receiver_map) { | 1157 Handle<Map> receiver_map) { |
| 1153 ElementsKind elements_kind = receiver_map->elements_kind(); | 1158 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 1154 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 1159 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 1155 Handle<Code> stub; | 1160 Handle<Code> stub; |
| 1156 if (receiver_map->has_fast_elements() || | 1161 if (receiver_map->has_fast_elements() || |
| 1157 receiver_map->has_external_array_elements() || | 1162 receiver_map->has_external_array_elements() || |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1182 | 1187 |
| 1183 void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) { | 1188 void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) { |
| 1184 Handle<Code> code(masm->isolate()->builtins()->builtin(name)); | 1189 Handle<Code> code(masm->isolate()->builtins()->builtin(name)); |
| 1185 GenerateTailCall(masm, code); | 1190 GenerateTailCall(masm, code); |
| 1186 } | 1191 } |
| 1187 | 1192 |
| 1188 | 1193 |
| 1189 void BaseLoadStoreStubCompiler::InitializeRegisters() { | 1194 void BaseLoadStoreStubCompiler::InitializeRegisters() { |
| 1190 if (kind_ == Code::LOAD_IC) { | 1195 if (kind_ == Code::LOAD_IC) { |
| 1191 registers_ = LoadStubCompiler::registers(); | 1196 registers_ = LoadStubCompiler::registers(); |
| 1192 } else if (kind_ == Code::KEYED_LOAD_IC) { | |
| 1193 registers_ = KeyedLoadStubCompiler::registers(); | |
| 1194 } else if (kind_ == Code::STORE_IC) { | 1197 } else if (kind_ == Code::STORE_IC) { |
| 1195 registers_ = StoreStubCompiler::registers(); | 1198 registers_ = StoreStubCompiler::registers(); |
| 1196 } else { | 1199 } else { |
| 1197 registers_ = KeyedStoreStubCompiler::registers(); | 1200 registers_ = KeyedStoreStubCompiler::registers(); |
| 1198 } | 1201 } |
| 1199 } | 1202 } |
| 1200 | 1203 |
| 1201 | 1204 |
| 1202 Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, | 1205 Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, |
| 1203 Code::StubType type, | 1206 Code::StubType type, |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1430 Handle<FunctionTemplateInfo>( | 1433 Handle<FunctionTemplateInfo>( |
| 1431 FunctionTemplateInfo::cast(signature->receiver())); | 1434 FunctionTemplateInfo::cast(signature->receiver())); |
| 1432 } | 1435 } |
| 1433 } | 1436 } |
| 1434 | 1437 |
| 1435 is_simple_api_call_ = true; | 1438 is_simple_api_call_ = true; |
| 1436 } | 1439 } |
| 1437 | 1440 |
| 1438 | 1441 |
| 1439 } } // namespace v8::internal | 1442 } } // namespace v8::internal |
| OLD | NEW |