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/stub-cache.cc

Issue 424743002: Clean up name distinction between Keyed ICs and Element Handlers (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
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 Code::StubType type) { 122 Code::StubType type) {
123 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); 123 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
124 124
125 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), 125 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags),
126 name->GetIsolate()); 126 name->GetIsolate());
127 if (probe->IsCode()) return Handle<Code>::cast(probe); 127 if (probe->IsCode()) return Handle<Code>::cast(probe);
128 return Handle<Code>::null(); 128 return Handle<Code>::null();
129 } 129 }
130 130
131 131
132 Handle<Code> PropertyICCompiler::ComputeMonomorphicIC( 132 Handle<Code> PropertyICCompiler::ComputeMonomorphic(
133 Code::Kind kind, Handle<Name> name, Handle<HeapType> type, 133 Code::Kind kind, Handle<Name> name, Handle<HeapType> type,
134 Handle<Code> handler, ExtraICState extra_ic_state) { 134 Handle<Code> handler, ExtraICState extra_ic_state) {
135 CacheHolderFlag flag; 135 CacheHolderFlag flag;
136 Isolate* isolate = name->GetIsolate(); 136 Isolate* isolate = name->GetIsolate();
137 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag); 137 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag);
138 138
139 Handle<Code> ic; 139 Handle<Code> ic;
140 // There are multiple string maps that all use the same prototype. That 140 // There are multiple string maps that all use the same prototype. That
141 // prototype cannot hold multiple handlers, one for each of the string maps, 141 // prototype cannot hold multiple handlers, one for each of the string maps,
142 // for a single name. Hence, turn off caching of the IC. 142 // for a single name. Hence, turn off caching of the IC.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); 198 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
199 if (!handler.is_null()) return handler; 199 if (!handler.is_null()) return handler;
200 200
201 NamedLoadHandlerCompiler compiler(isolate, flag); 201 NamedLoadHandlerCompiler compiler(isolate, flag);
202 handler = compiler.CompileLoadNonexistent(type, last, cache_name); 202 handler = compiler.CompileLoadNonexistent(type, last, cache_name);
203 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); 203 Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
204 return handler; 204 return handler;
205 } 205 }
206 206
207 207
208 Handle<Code> PropertyICCompiler::ComputeKeyedLoadElement( 208 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
209 Handle<Map> receiver_map) { 209 Handle<Map> receiver_map) {
210 Isolate* isolate = receiver_map->GetIsolate(); 210 Isolate* isolate = receiver_map->GetIsolate();
211 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 211 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
212 Handle<Name> name = isolate->factory()->KeyedLoadElementMonomorphic_string(); 212 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
213 213
214 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); 214 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
215 if (probe->IsCode()) return Handle<Code>::cast(probe); 215 if (probe->IsCode()) return Handle<Code>::cast(probe);
216 216
217 ElementsKind elements_kind = receiver_map->elements_kind(); 217 ElementsKind elements_kind = receiver_map->elements_kind();
218 Handle<Code> stub; 218 Handle<Code> stub;
219 if (receiver_map->has_fast_elements() || 219 if (receiver_map->has_fast_elements() ||
220 receiver_map->has_external_array_elements() || 220 receiver_map->has_external_array_elements() ||
221 receiver_map->has_fixed_typed_array_elements()) { 221 receiver_map->has_fixed_typed_array_elements()) {
222 stub = KeyedLoadFastElementStub( 222 stub = LoadFastElementStub(isolate,
223 isolate, receiver_map->instance_type() == JS_ARRAY_TYPE, 223 receiver_map->instance_type() == JS_ARRAY_TYPE,
224 elements_kind).GetCode(); 224 elements_kind).GetCode();
225 } else { 225 } else {
226 stub = FLAG_compiled_keyed_dictionary_loads 226 stub = FLAG_compiled_keyed_dictionary_loads
227 ? KeyedLoadDictionaryElementStub(isolate).GetCode() 227 ? LoadDictionaryElementStub(isolate).GetCode()
228 : KeyedLoadDictionaryElementPlatformStub(isolate).GetCode(); 228 : LoadDictionaryElementPlatformStub(isolate).GetCode();
229 } 229 }
230 PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC); 230 PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
231 Handle<Code> code = 231 Handle<Code> code =
232 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub, 232 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
233 isolate->factory()->empty_string(), ELEMENT); 233 isolate->factory()->empty_string(), ELEMENT);
234 234
235 Map::UpdateCodeCache(receiver_map, name, code); 235 Map::UpdateCodeCache(receiver_map, name, code);
236 return code; 236 return code;
237 } 237 }
238 238
239 239
240 Handle<Code> PropertyICCompiler::ComputeKeyedStoreElement( 240 Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic(
241 Handle<Map> receiver_map, StrictMode strict_mode, 241 Handle<Map> receiver_map, StrictMode strict_mode,
242 KeyedAccessStoreMode store_mode) { 242 KeyedAccessStoreMode store_mode) {
243 Isolate* isolate = receiver_map->GetIsolate(); 243 Isolate* isolate = receiver_map->GetIsolate();
244 ExtraICState extra_state = 244 ExtraICState extra_state =
245 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); 245 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
246 Code::Flags flags = 246 Code::Flags flags =
247 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state); 247 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state);
248 248
249 ASSERT(store_mode == STANDARD_STORE || 249 ASSERT(store_mode == STANDARD_STORE ||
250 store_mode == STORE_AND_GROW_NO_TRANSITION || 250 store_mode == STORE_AND_GROW_NO_TRANSITION ||
251 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 251 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
252 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 252 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
253 253
254 Handle<String> name = 254 Handle<String> name = isolate->factory()->KeyedStoreMonomorphic_string();
255 isolate->factory()->KeyedStoreElementMonomorphic_string();
256 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); 255 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
257 if (probe->IsCode()) return Handle<Code>::cast(probe); 256 if (probe->IsCode()) return Handle<Code>::cast(probe);
258 257
259 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); 258 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
260 Handle<Code> code = 259 Handle<Code> code =
261 compiler.CompileIndexedStoreMonomorphic(receiver_map, store_mode); 260 compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
262 261
263 Map::UpdateCodeCache(receiver_map, name, code); 262 Map::UpdateCodeCache(receiver_map, name, code);
264 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) 263 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
265 == store_mode); 264 == store_mode);
266 return code; 265 return code;
267 } 266 }
268 267
269 268
270 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type) 269 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
271 270
272 static void FillCache(Isolate* isolate, Handle<Code> code) { 271 static void FillCache(Isolate* isolate, Handle<Code> code) {
273 Handle<UnseededNumberDictionary> dictionary = 272 Handle<UnseededNumberDictionary> dictionary =
274 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 273 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
275 code->flags(), 274 code->flags(),
276 code); 275 code);
277 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 276 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
278 } 277 }
279 278
280 279
281 Code* PropertyICCompiler::FindPreMonomorphicIC(Isolate* isolate, 280 Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
282 Code::Kind kind, 281 ExtraICState state) {
283 ExtraICState state) {
284 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 282 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
285 UnseededNumberDictionary* dictionary = 283 UnseededNumberDictionary* dictionary =
286 isolate->heap()->non_monomorphic_cache(); 284 isolate->heap()->non_monomorphic_cache();
287 int entry = dictionary->FindEntry(isolate, flags); 285 int entry = dictionary->FindEntry(isolate, flags);
288 ASSERT(entry != -1); 286 ASSERT(entry != -1);
289 Object* code = dictionary->ValueAt(entry); 287 Object* code = dictionary->ValueAt(entry);
290 // This might be called during the marking phase of the collector 288 // This might be called during the marking phase of the collector
291 // hence the unchecked cast. 289 // hence the unchecked cast.
292 return reinterpret_cast<Code*>(code); 290 return reinterpret_cast<Code*>(code);
293 } 291 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 360
363 if (!receiver_map->is_shared()) { 361 if (!receiver_map->is_shared()) {
364 Map::UpdateCodeCache(receiver_map, name, ic); 362 Map::UpdateCodeCache(receiver_map, name, ic);
365 } 363 }
366 364
367 return ic; 365 return ic;
368 } 366 }
369 367
370 368
371 // TODO(verwaest): Change this method so it takes in a TypeHandleList. 369 // TODO(verwaest): Change this method so it takes in a TypeHandleList.
372 Handle<Code> PropertyICCompiler::ComputeLoadElementPolymorphic( 370 Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
373 MapHandleList* receiver_maps) { 371 MapHandleList* receiver_maps) {
374 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); 372 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
375 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 373 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
376 Handle<PolymorphicCodeCache> cache = 374 Handle<PolymorphicCodeCache> cache =
377 isolate->factory()->polymorphic_code_cache(); 375 isolate->factory()->polymorphic_code_cache();
378 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 376 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
379 if (probe->IsCode()) return Handle<Code>::cast(probe); 377 if (probe->IsCode()) return Handle<Code>::cast(probe);
380 378
381 TypeHandleList types(receiver_maps->length()); 379 TypeHandleList types(receiver_maps->length());
382 for (int i = 0; i < receiver_maps->length(); i++) { 380 for (int i = 0; i < receiver_maps->length(); i++) {
383 types.Add(HeapType::Class(receiver_maps->at(i), isolate)); 381 types.Add(HeapType::Class(receiver_maps->at(i), isolate));
384 } 382 }
385 CodeHandleList handlers(receiver_maps->length()); 383 CodeHandleList handlers(receiver_maps->length());
386 IndexedHandlerCompiler compiler(isolate); 384 ElementHandlerCompiler compiler(isolate);
387 compiler.CompileElementHandlers(receiver_maps, &handlers); 385 compiler.CompileElementHandlers(receiver_maps, &handlers);
388 PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC); 386 PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
389 Handle<Code> code = ic_compiler.CompilePolymorphic( 387 Handle<Code> code = ic_compiler.CompilePolymorphic(
390 &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL, 388 &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL,
391 ELEMENT); 389 ELEMENT);
392 390
393 isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); 391 isolate->counters()->keyed_load_polymorphic_stubs()->Increment();
394 392
395 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 393 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
396 return code; 394 return code;
397 } 395 }
398 396
399 397
400 Handle<Code> PropertyICCompiler::ComputePolymorphicIC( 398 Handle<Code> PropertyICCompiler::ComputePolymorphic(
401 Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, 399 Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers,
402 int valid_types, Handle<Name> name, ExtraICState extra_ic_state) { 400 int valid_types, Handle<Name> name, ExtraICState extra_ic_state) {
403 Handle<Code> handler = handlers->at(0); 401 Handle<Code> handler = handlers->at(0);
404 Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL; 402 Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL;
405 ASSERT(kind == Code::LOAD_IC || kind == Code::STORE_IC); 403 ASSERT(kind == Code::LOAD_IC || kind == Code::STORE_IC);
406 PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state); 404 PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state);
407 return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY); 405 return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY);
408 } 406 }
409 407
410 408
411 Handle<Code> PropertyICCompiler::ComputeStoreElementPolymorphic( 409 Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
412 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, 410 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
413 StrictMode strict_mode) { 411 StrictMode strict_mode) {
414 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); 412 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
415 ASSERT(store_mode == STANDARD_STORE || 413 ASSERT(store_mode == STANDARD_STORE ||
416 store_mode == STORE_AND_GROW_NO_TRANSITION || 414 store_mode == STORE_AND_GROW_NO_TRANSITION ||
417 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 415 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
418 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 416 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
419 Handle<PolymorphicCodeCache> cache = 417 Handle<PolymorphicCodeCache> cache =
420 isolate->factory()->polymorphic_code_cache(); 418 isolate->factory()->polymorphic_code_cache();
421 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( 419 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(
422 strict_mode, store_mode); 420 strict_mode, store_mode);
423 Code::Flags flags = 421 Code::Flags flags =
424 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 422 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
425 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 423 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
426 if (probe->IsCode()) return Handle<Code>::cast(probe); 424 if (probe->IsCode()) return Handle<Code>::cast(probe);
427 425
428 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); 426 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
429 Handle<Code> code = 427 Handle<Code> code =
430 compiler.CompileIndexedStorePolymorphic(receiver_maps, store_mode); 428 compiler.CompileKeyedStorePolymorphic(receiver_maps, store_mode);
431 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 429 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
432 return code; 430 return code;
433 } 431 }
434 432
435 433
436 void StubCache::Clear() { 434 void StubCache::Clear() {
437 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); 435 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
438 for (int i = 0; i < kPrimaryTableSize; i++) { 436 for (int i = 0; i < kPrimaryTableSize; i++) {
439 primary_[i].key = isolate()->heap()->empty_string(); 437 primary_[i].key = isolate()->heap()->empty_string();
440 primary_[i].map = NULL; 438 primary_[i].map = NULL;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 LookupIterator it(receiver, name, holder); 600 LookupIterator it(receiver, name, holder);
603 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 601 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
604 isolate, result, JSObject::GetProperty(&it)); 602 isolate, result, JSObject::GetProperty(&it));
605 603
606 if (it.IsFound()) return *result; 604 if (it.IsFound()) return *result;
607 605
608 return ThrowReferenceError(isolate, Name::cast(args[0])); 606 return ThrowReferenceError(isolate, Name::cast(args[0]));
609 } 607 }
610 608
611 609
612 RUNTIME_FUNCTION(StoreInterceptorProperty) { 610 RUNTIME_FUNCTION(StorePropertyWithInterceptor) {
613 HandleScope scope(isolate); 611 HandleScope scope(isolate);
614 ASSERT(args.length() == 3); 612 ASSERT(args.length() == 3);
615 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 613 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
616 Handle<JSObject> receiver = args.at<JSObject>(0); 614 Handle<JSObject> receiver = args.at<JSObject>(0);
617 Handle<Name> name = args.at<Name>(1); 615 Handle<Name> name = args.at<Name>(1);
618 Handle<Object> value = args.at<Object>(2); 616 Handle<Object> value = args.at<Object>(2);
619 #ifdef DEBUG 617 #ifdef DEBUG
620 if (receiver->IsJSGlobalProxy()) { 618 if (receiver->IsJSGlobalProxy()) {
621 PrototypeIterator iter(isolate, receiver); 619 PrototypeIterator iter(isolate, receiver);
622 ASSERT(iter.IsAtEnd() || 620 ASSERT(iter.IsAtEnd() ||
623 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)) 621 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter))
624 ->HasNamedInterceptor()); 622 ->HasNamedInterceptor());
625 } else { 623 } else {
626 ASSERT(receiver->HasNamedInterceptor()); 624 ASSERT(receiver->HasNamedInterceptor());
627 } 625 }
628 #endif 626 #endif
629 Handle<Object> result; 627 Handle<Object> result;
630 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 628 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
631 isolate, result, 629 isolate, result,
632 JSObject::SetProperty(receiver, name, value, ic.strict_mode())); 630 JSObject::SetProperty(receiver, name, value, ic.strict_mode()));
633 return *result; 631 return *result;
634 } 632 }
635 633
636 634
637 RUNTIME_FUNCTION(KeyedLoadPropertyWithInterceptor) { 635 RUNTIME_FUNCTION(LoadElementWithInterceptor) {
638 HandleScope scope(isolate); 636 HandleScope scope(isolate);
639 Handle<JSObject> receiver = args.at<JSObject>(0); 637 Handle<JSObject> receiver = args.at<JSObject>(0);
640 ASSERT(args.smi_at(1) >= 0); 638 ASSERT(args.smi_at(1) >= 0);
641 uint32_t index = args.smi_at(1); 639 uint32_t index = args.smi_at(1);
642 Handle<Object> result; 640 Handle<Object> result;
643 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 641 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
644 isolate, result, 642 isolate, result,
645 JSObject::GetElementWithInterceptor(receiver, receiver, index)); 643 JSObject::GetElementWithInterceptor(receiver, receiver, index));
646 return *result; 644 return *result;
647 } 645 }
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 const CallOptimization& call_optimization) { 1079 const CallOptimization& call_optimization) {
1082 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); 1080 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1083 Register values[] = { value() }; 1081 Register values[] = { value() };
1084 GenerateFastApiCall( 1082 GenerateFastApiCall(
1085 masm(), call_optimization, handle(object->map()), 1083 masm(), call_optimization, handle(object->map()),
1086 receiver(), scratch1(), true, 1, values); 1084 receiver(), scratch1(), true, 1, values);
1087 return GetCode(kind(), Code::FAST, name); 1085 return GetCode(kind(), Code::FAST, name);
1088 } 1086 }
1089 1087
1090 1088
1091 Handle<Code> PropertyICCompiler::CompileIndexedStoreMonomorphic( 1089 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
1092 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { 1090 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
1093 ElementsKind elements_kind = receiver_map->elements_kind(); 1091 ElementsKind elements_kind = receiver_map->elements_kind();
1094 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 1092 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
1095 Handle<Code> stub; 1093 Handle<Code> stub;
1096 if (receiver_map->has_fast_elements() || 1094 if (receiver_map->has_fast_elements() ||
1097 receiver_map->has_external_array_elements() || 1095 receiver_map->has_external_array_elements() ||
1098 receiver_map->has_fixed_typed_array_elements()) { 1096 receiver_map->has_fixed_typed_array_elements()) {
1099 stub = KeyedStoreFastElementStub(isolate(), is_jsarray, elements_kind, 1097 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
1100 store_mode).GetCode(); 1098 store_mode).GetCode();
1101 } else { 1099 } else {
1102 stub = KeyedStoreElementStub(isolate(), is_jsarray, elements_kind, 1100 stub = StoreElementStub(isolate(), is_jsarray, elements_kind, store_mode)
1103 store_mode).GetCode(); 1101 .GetCode();
1104 } 1102 }
1105 1103
1106 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1104 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1107 1105
1108 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); 1106 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
1109 1107
1110 return GetCode(kind(), Code::NORMAL, factory()->empty_string()); 1108 return GetCode(kind(), Code::NORMAL, factory()->empty_string());
1111 } 1109 }
1112 1110
1113 1111
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, 1146 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
1149 Code::StubType type, 1147 Code::StubType type,
1150 Handle<Name> name) { 1148 Handle<Name> name) {
1151 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder()); 1149 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder());
1152 Handle<Code> code = GetCodeWithFlags(flags, name); 1150 Handle<Code> code = GetCodeWithFlags(flags, name);
1153 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name)); 1151 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name));
1154 return code; 1152 return code;
1155 } 1153 }
1156 1154
1157 1155
1158 void IndexedHandlerCompiler::CompileElementHandlers( 1156 void ElementHandlerCompiler::CompileElementHandlers(
1159 MapHandleList* receiver_maps, CodeHandleList* handlers) { 1157 MapHandleList* receiver_maps, CodeHandleList* handlers) {
1160 for (int i = 0; i < receiver_maps->length(); ++i) { 1158 for (int i = 0; i < receiver_maps->length(); ++i) {
1161 Handle<Map> receiver_map = receiver_maps->at(i); 1159 Handle<Map> receiver_map = receiver_maps->at(i);
1162 Handle<Code> cached_stub; 1160 Handle<Code> cached_stub;
1163 1161
1164 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1162 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1165 cached_stub = isolate()->builtins()->KeyedLoadIC_String(); 1163 cached_stub = isolate()->builtins()->KeyedLoadIC_String();
1166 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 1164 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1167 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow(); 1165 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
1168 } else { 1166 } else {
1169 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1167 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1170 ElementsKind elements_kind = receiver_map->elements_kind(); 1168 ElementsKind elements_kind = receiver_map->elements_kind();
1171 1169
1172 if (IsFastElementsKind(elements_kind) || 1170 if (IsFastElementsKind(elements_kind) ||
1173 IsExternalArrayElementsKind(elements_kind) || 1171 IsExternalArrayElementsKind(elements_kind) ||
1174 IsFixedTypedArrayElementsKind(elements_kind)) { 1172 IsFixedTypedArrayElementsKind(elements_kind)) {
1175 cached_stub = 1173 cached_stub = LoadFastElementStub(isolate(), is_js_array, elements_kind)
1176 KeyedLoadFastElementStub(isolate(), 1174 .GetCode();
1177 is_js_array,
1178 elements_kind).GetCode();
1179 } else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) { 1175 } else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
1180 cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments(); 1176 cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments();
1181 } else { 1177 } else {
1182 ASSERT(elements_kind == DICTIONARY_ELEMENTS); 1178 ASSERT(elements_kind == DICTIONARY_ELEMENTS);
1183 cached_stub = 1179 cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
1184 KeyedLoadDictionaryElementStub(isolate()).GetCode();
1185 } 1180 }
1186 } 1181 }
1187 1182
1188 handlers->Add(cached_stub); 1183 handlers->Add(cached_stub);
1189 } 1184 }
1190 } 1185 }
1191 1186
1192 1187
1193 Handle<Code> PropertyICCompiler::CompileIndexedStorePolymorphic( 1188 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
1194 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) { 1189 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
1195 // Collect MONOMORPHIC stubs for all |receiver_maps|. 1190 // Collect MONOMORPHIC stubs for all |receiver_maps|.
1196 CodeHandleList handlers(receiver_maps->length()); 1191 CodeHandleList handlers(receiver_maps->length());
1197 MapHandleList transitioned_maps(receiver_maps->length()); 1192 MapHandleList transitioned_maps(receiver_maps->length());
1198 for (int i = 0; i < receiver_maps->length(); ++i) { 1193 for (int i = 0; i < receiver_maps->length(); ++i) {
1199 Handle<Map> receiver_map(receiver_maps->at(i)); 1194 Handle<Map> receiver_map(receiver_maps->at(i));
1200 Handle<Code> cached_stub; 1195 Handle<Code> cached_stub;
1201 Handle<Map> transitioned_map = 1196 Handle<Map> transitioned_map =
1202 receiver_map->FindTransitionedMap(receiver_maps); 1197 receiver_map->FindTransitionedMap(receiver_maps);
1203 1198
1204 // TODO(mvstanton): The code below is doing pessimistic elements 1199 // TODO(mvstanton): The code below is doing pessimistic elements
1205 // transitions. I would like to stop doing that and rely on Allocation Site 1200 // transitions. I would like to stop doing that and rely on Allocation Site
1206 // Tracking to do a better job of ensuring the data types are what they need 1201 // Tracking to do a better job of ensuring the data types are what they need
1207 // to be. Not all the elements are in place yet, pessimistic elements 1202 // to be. Not all the elements are in place yet, pessimistic elements
1208 // transitions are still important for performance. 1203 // transitions are still important for performance.
1209 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1204 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1210 ElementsKind elements_kind = receiver_map->elements_kind(); 1205 ElementsKind elements_kind = receiver_map->elements_kind();
1211 if (!transitioned_map.is_null()) { 1206 if (!transitioned_map.is_null()) {
1212 cached_stub = 1207 cached_stub =
1213 ElementsTransitionAndStoreStub(isolate(), elements_kind, 1208 ElementsTransitionAndStoreStub(isolate(), elements_kind,
1214 transitioned_map->elements_kind(), 1209 transitioned_map->elements_kind(),
1215 is_js_array, store_mode).GetCode(); 1210 is_js_array, store_mode).GetCode();
1216 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 1211 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1217 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow(); 1212 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
1218 } else { 1213 } else {
1219 if (receiver_map->has_fast_elements() || 1214 if (receiver_map->has_fast_elements() ||
1220 receiver_map->has_external_array_elements() || 1215 receiver_map->has_external_array_elements() ||
1221 receiver_map->has_fixed_typed_array_elements()) { 1216 receiver_map->has_fixed_typed_array_elements()) {
1222 cached_stub = 1217 cached_stub = StoreFastElementStub(isolate(), is_js_array,
1223 KeyedStoreFastElementStub(isolate(), is_js_array, elements_kind, 1218 elements_kind, store_mode).GetCode();
1224 store_mode).GetCode();
1225 } else { 1219 } else {
1226 cached_stub = 1220 cached_stub = StoreElementStub(isolate(), is_js_array, elements_kind,
1227 KeyedStoreElementStub(isolate(), is_js_array, elements_kind, 1221 store_mode).GetCode();
1228 store_mode).GetCode();
1229 } 1222 }
1230 } 1223 }
1231 ASSERT(!cached_stub.is_null()); 1224 ASSERT(!cached_stub.is_null());
1232 handlers.Add(cached_stub); 1225 handlers.Add(cached_stub);
1233 transitioned_maps.Add(transitioned_map); 1226 transitioned_maps.Add(transitioned_map);
1234 } 1227 }
1235 1228
1236 Handle<Code> code = CompileIndexedStorePolymorphic(receiver_maps, &handlers, 1229 Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers,
1237 &transitioned_maps); 1230 &transitioned_maps);
1238 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 1231 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1239 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0)); 1232 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0));
1240 return code; 1233 return code;
1241 } 1234 }
1242 1235
1243 1236
1244 void IndexedHandlerCompiler::GenerateStoreDictionaryElement( 1237 void ElementHandlerCompiler::GenerateStoreDictionaryElement(
1245 MacroAssembler* masm) { 1238 MacroAssembler* masm) {
1246 KeyedStoreIC::GenerateSlow(masm); 1239 KeyedStoreIC::GenerateSlow(masm);
1247 } 1240 }
1248 1241
1249 1242
1250 CallOptimization::CallOptimization(LookupResult* lookup) { 1243 CallOptimization::CallOptimization(LookupResult* lookup) {
1251 if (lookup->IsFound() && 1244 if (lookup->IsFound() &&
1252 lookup->IsCacheable() && 1245 lookup->IsCacheable() &&
1253 lookup->IsConstantFunction()) { 1246 lookup->IsConstantFunction()) {
1254 // We only optimize constant function calls. 1247 // We only optimize constant function calls.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 Handle<FunctionTemplateInfo>( 1350 Handle<FunctionTemplateInfo>(
1358 FunctionTemplateInfo::cast(signature->receiver())); 1351 FunctionTemplateInfo::cast(signature->receiver()));
1359 } 1352 }
1360 } 1353 }
1361 1354
1362 is_simple_api_call_ = true; 1355 is_simple_api_call_ = true;
1363 } 1356 }
1364 1357
1365 1358
1366 } } // namespace v8::internal 1359 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698