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 |