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

Side by Side Diff: src/ic/ic-compiler.cc

Issue 497083002: Move handler compilers to handler-compiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix include 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/ic/ic-compiler.h ('k') | src/ic/x64/handler-compiler-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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/ic/call-optimization.h" 7 #include "src/ic/handler-compiler.h"
8 #include "src/ic/ic-inl.h" 8 #include "src/ic/ic-inl.h"
9 #include "src/ic/ic-compiler.h" 9 #include "src/ic/ic-compiler.h"
10 10
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 Handle<Code> PropertyICCompiler::Find(Handle<Name> name, 16 Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
17 Handle<Map> stub_holder, Code::Kind kind, 17 Handle<Map> stub_holder, Code::Kind kind,
18 ExtraICState extra_state, 18 ExtraICState extra_state,
19 CacheHolderFlag cache_holder) { 19 CacheHolderFlag cache_holder) {
20 Code::Flags flags = 20 Code::Flags flags =
21 Code::ComputeMonomorphicFlags(kind, extra_state, cache_holder); 21 Code::ComputeMonomorphicFlags(kind, extra_state, cache_holder);
22 Object* probe = stub_holder->FindInCodeCache(*name, flags); 22 Object* probe = stub_holder->FindInCodeCache(*name, flags);
23 if (probe->IsCode()) return handle(Code::cast(probe)); 23 if (probe->IsCode()) return handle(Code::cast(probe));
24 return Handle<Code>::null(); 24 return Handle<Code>::null();
25 } 25 }
26 26
27 27
28 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, 28 bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
29 Handle<Map> stub_holder, 29 for (int i = 0; i < types->length(); ++i) {
30 Code::Kind kind, 30 if (types->at(i)->Is(HeapType::Number())) return true;
31 CacheHolderFlag cache_holder, 31 }
32 Code::StubType type) { 32 return false;
33 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder);
34 Object* probe = stub_holder->FindInCodeCache(*name, flags);
35 if (probe->IsCode()) return handle(Code::cast(probe));
36 return Handle<Code>::null();
37 } 33 }
38 34
39 35
36 Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
37 Handle<Code> handler,
38 Handle<Name> name,
39 IcCheckType check) {
40 TypeHandleList types(1);
41 CodeHandleList handlers(1);
42 types.Add(type);
43 handlers.Add(handler);
44 Code::StubType stub_type = handler->type();
45 return CompilePolymorphic(&types, &handlers, name, stub_type, check);
46 }
47
48
40 Handle<Code> PropertyICCompiler::ComputeMonomorphic( 49 Handle<Code> PropertyICCompiler::ComputeMonomorphic(
41 Code::Kind kind, Handle<Name> name, Handle<HeapType> type, 50 Code::Kind kind, Handle<Name> name, Handle<HeapType> type,
42 Handle<Code> handler, ExtraICState extra_ic_state) { 51 Handle<Code> handler, ExtraICState extra_ic_state) {
43 Isolate* isolate = name->GetIsolate(); 52 Isolate* isolate = name->GetIsolate();
44 if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) || 53 if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) ||
45 handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) { 54 handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) {
46 name = isolate->factory()->normal_ic_symbol(); 55 name = isolate->factory()->normal_ic_symbol();
47 } 56 }
48 57
49 CacheHolderFlag flag; 58 CacheHolderFlag flag;
(...skipping 17 matching lines...) Expand all
67 #endif 76 #endif
68 77
69 PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag); 78 PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
70 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); 79 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
71 80
72 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); 81 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
73 return ic; 82 return ic;
74 } 83 }
75 84
76 85
77 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
78 Handle<Name> name, Handle<HeapType> type) {
79 Isolate* isolate = name->GetIsolate();
80 Handle<Map> receiver_map = IC::TypeToMap(*type, isolate);
81 if (receiver_map->prototype()->IsNull()) {
82 // TODO(jkummerow/verwaest): If there is no prototype and the property
83 // is nonexistent, introduce a builtin to handle this (fast properties
84 // -> return undefined, dictionary properties -> do negative lookup).
85 return Handle<Code>();
86 }
87 CacheHolderFlag flag;
88 Handle<Map> stub_holder_map =
89 IC::GetHandlerCacheHolder(*type, false, isolate, &flag);
90
91 // If no dictionary mode objects are present in the prototype chain, the load
92 // nonexistent IC stub can be shared for all names for a given map and we use
93 // the empty string for the map cache in that case. If there are dictionary
94 // mode objects involved, we need to do negative lookups in the stub and
95 // therefore the stub will be specific to the name.
96 Handle<Name> cache_name =
97 receiver_map->is_dictionary_map()
98 ? name
99 : Handle<Name>::cast(isolate->factory()->nonexistent_symbol());
100 Handle<Map> current_map = stub_holder_map;
101 Handle<JSObject> last(JSObject::cast(receiver_map->prototype()));
102 while (true) {
103 if (current_map->is_dictionary_map()) cache_name = name;
104 if (current_map->prototype()->IsNull()) break;
105 last = handle(JSObject::cast(current_map->prototype()));
106 current_map = handle(last->map());
107 }
108 // Compile the stub that is either shared for all names or
109 // name specific if there are global objects involved.
110 Handle<Code> handler = PropertyHandlerCompiler::Find(
111 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
112 if (!handler.is_null()) return handler;
113
114 NamedLoadHandlerCompiler compiler(isolate, type, last, flag);
115 handler = compiler.CompileLoadNonexistent(cache_name);
116 Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
117 return handler;
118 }
119
120
121 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic( 86 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
122 Handle<Map> receiver_map) { 87 Handle<Map> receiver_map) {
123 Isolate* isolate = receiver_map->GetIsolate(); 88 Isolate* isolate = receiver_map->GetIsolate();
124 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 89 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
125 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string(); 90 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
126 91
127 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); 92 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
128 if (probe->IsCode()) return Handle<Code>::cast(probe); 93 if (probe->IsCode()) return Handle<Code>::cast(probe);
129 94
130 ElementsKind elements_kind = receiver_map->elements_kind(); 95 ElementsKind elements_kind = receiver_map->elements_kind();
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 358
394 359
395 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) { 360 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
396 StoreIC::GenerateMegamorphic(masm()); 361 StoreIC::GenerateMegamorphic(masm());
397 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); 362 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
398 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); 363 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
399 return code; 364 return code;
400 } 365 }
401 366
402 367
403 #define __ ACCESS_MASM(masm())
404
405
406 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
407 Handle<Name> name,
408 Label* miss) {
409 PrototypeCheckType check_type = CHECK_ALL_MAPS;
410 int function_index = -1;
411 if (type()->Is(HeapType::String())) {
412 function_index = Context::STRING_FUNCTION_INDEX;
413 } else if (type()->Is(HeapType::Symbol())) {
414 function_index = Context::SYMBOL_FUNCTION_INDEX;
415 } else if (type()->Is(HeapType::Number())) {
416 function_index = Context::NUMBER_FUNCTION_INDEX;
417 } else if (type()->Is(HeapType::Boolean())) {
418 function_index = Context::BOOLEAN_FUNCTION_INDEX;
419 } else {
420 check_type = SKIP_RECEIVER;
421 }
422
423 if (check_type == CHECK_ALL_MAPS) {
424 GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
425 scratch1(), miss);
426 Object* function = isolate()->native_context()->get(function_index);
427 Object* prototype = JSFunction::cast(function)->instance_prototype();
428 set_type_for_object(handle(prototype, isolate()));
429 object_reg = scratch1();
430 }
431
432 // Check that the maps starting from the prototype haven't changed.
433 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
434 miss, check_type);
435 }
436
437
438 // Frontend for store uses the name register. It has to be restored before a
439 // miss.
440 Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
441 Handle<Name> name,
442 Label* miss) {
443 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
444 miss, SKIP_RECEIVER);
445 }
446
447
448 bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
449 for (int i = 0; i < types->length(); ++i) {
450 if (types->at(i)->Is(HeapType::Number())) return true;
451 }
452 return false;
453 }
454
455
456 Register PropertyHandlerCompiler::Frontend(Register object_reg,
457 Handle<Name> name) {
458 Label miss;
459 Register reg = FrontendHeader(object_reg, name, &miss);
460 FrontendFooter(name, &miss);
461 return reg;
462 }
463
464
465 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
466 Label* miss,
467 Register scratch1,
468 Register scratch2) {
469 Register holder_reg;
470 Handle<Map> last_map;
471 if (holder().is_null()) {
472 holder_reg = receiver();
473 last_map = IC::TypeToMap(*type(), isolate());
474 // If |type| has null as its prototype, |holder()| is
475 // Handle<JSObject>::null().
476 DCHECK(last_map->prototype() == isolate()->heap()->null_value());
477 } else {
478 holder_reg = FrontendHeader(receiver(), name, miss);
479 last_map = handle(holder()->map());
480 }
481
482 if (last_map->is_dictionary_map()) {
483 if (last_map->IsJSGlobalObjectMap()) {
484 Handle<JSGlobalObject> global =
485 holder().is_null()
486 ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value())
487 : Handle<JSGlobalObject>::cast(holder());
488 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss);
489 } else {
490 if (!name->IsUniqueName()) {
491 DCHECK(name->IsString());
492 name = factory()->InternalizeString(Handle<String>::cast(name));
493 }
494 DCHECK(holder().is_null() ||
495 holder()->property_dictionary()->FindEntry(name) ==
496 NameDictionary::kNotFound);
497 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1,
498 scratch2);
499 }
500 }
501 }
502
503
504 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name,
505 FieldIndex field) {
506 Register reg = Frontend(receiver(), name);
507 __ Move(receiver(), reg);
508 LoadFieldStub stub(isolate(), field);
509 GenerateTailCall(masm(), stub.GetCode());
510 return GetCode(kind(), Code::FAST, name);
511 }
512
513
514 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
515 int constant_index) {
516 Register reg = Frontend(receiver(), name);
517 __ Move(receiver(), reg);
518 LoadConstantStub stub(isolate(), constant_index);
519 GenerateTailCall(masm(), stub.GetCode());
520 return GetCode(kind(), Code::FAST, name);
521 }
522
523
524 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
525 Handle<Name> name) {
526 Label miss;
527 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
528 GenerateLoadConstant(isolate()->factory()->undefined_value());
529 FrontendFooter(name, &miss);
530 return GetCode(kind(), Code::FAST, name);
531 }
532
533
534 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
535 Handle<Name> name, Handle<ExecutableAccessorInfo> callback) {
536 Register reg = Frontend(receiver(), name);
537 GenerateLoadCallback(reg, callback);
538 return GetCode(kind(), Code::FAST, name);
539 }
540
541
542 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
543 Handle<Name> name, const CallOptimization& call_optimization) {
544 DCHECK(call_optimization.is_simple_api_call());
545 Frontend(receiver(), name);
546 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
547 GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
548 scratch1(), false, 0, NULL);
549 return GetCode(kind(), Code::FAST, name);
550 }
551
552
553 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
554 LookupIterator* it) {
555 // So far the most popular follow ups for interceptor loads are FIELD and
556 // ExecutableAccessorInfo, so inline only them. Other cases may be added
557 // later.
558 bool inline_followup = it->state() == LookupIterator::PROPERTY;
559 if (inline_followup) {
560 switch (it->property_kind()) {
561 case LookupIterator::DATA:
562 inline_followup = it->property_details().type() == FIELD;
563 break;
564 case LookupIterator::ACCESSOR: {
565 Handle<Object> accessors = it->GetAccessors();
566 inline_followup = accessors->IsExecutableAccessorInfo();
567 if (!inline_followup) break;
568 Handle<ExecutableAccessorInfo> info =
569 Handle<ExecutableAccessorInfo>::cast(accessors);
570 inline_followup = info->getter() != NULL &&
571 ExecutableAccessorInfo::IsCompatibleReceiverType(
572 isolate(), info, type());
573 }
574 }
575 }
576
577 Register reg = Frontend(receiver(), it->name());
578 if (inline_followup) {
579 // TODO(368): Compile in the whole chain: all the interceptors in
580 // prototypes and ultimate answer.
581 GenerateLoadInterceptorWithFollowup(it, reg);
582 } else {
583 GenerateLoadInterceptor(reg);
584 }
585 return GetCode(kind(), Code::FAST, it->name());
586 }
587
588
589 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
590 LookupIterator* it, Register interceptor_reg) {
591 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
592
593 set_type_for_object(holder());
594 set_holder(real_named_property_holder);
595 Register reg = Frontend(interceptor_reg, it->name());
596
597 switch (it->property_kind()) {
598 case LookupIterator::DATA: {
599 DCHECK_EQ(FIELD, it->property_details().type());
600 __ Move(receiver(), reg);
601 LoadFieldStub stub(isolate(), it->GetFieldIndex());
602 GenerateTailCall(masm(), stub.GetCode());
603 break;
604 }
605 case LookupIterator::ACCESSOR:
606 Handle<ExecutableAccessorInfo> info =
607 Handle<ExecutableAccessorInfo>::cast(it->GetAccessors());
608 DCHECK_NE(NULL, info->getter());
609 GenerateLoadCallback(reg, info);
610 }
611 }
612
613
614 Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
615 Handle<Code> handler,
616 Handle<Name> name,
617 IcCheckType check) {
618 TypeHandleList types(1);
619 CodeHandleList handlers(1);
620 types.Add(type);
621 handlers.Add(handler);
622 Code::StubType stub_type = handler->type();
623 return CompilePolymorphic(&types, &handlers, name, stub_type, check);
624 }
625
626
627 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
628 Handle<Name> name, Handle<JSFunction> getter) {
629 Frontend(receiver(), name);
630 GenerateLoadViaGetter(masm(), type(), receiver(), getter);
631 return GetCode(kind(), Code::FAST, name);
632 }
633
634
635 // TODO(verwaest): Cleanup. holder() is actually the receiver.
636 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
637 Handle<Map> transition, Handle<Name> name) {
638 Label miss, slow;
639
640 // Ensure no transitions to deprecated maps are followed.
641 __ CheckMapDeprecated(transition, scratch1(), &miss);
642
643 // Check that we are allowed to write this.
644 bool is_nonexistent = holder()->map() == transition->GetBackPointer();
645 if (is_nonexistent) {
646 // Find the top object.
647 Handle<JSObject> last;
648 PrototypeIterator iter(isolate(), holder());
649 while (!iter.IsAtEnd()) {
650 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
651 iter.Advance();
652 }
653 if (!last.is_null()) set_holder(last);
654 NonexistentFrontendHeader(name, &miss, scratch1(), scratch2());
655 } else {
656 FrontendHeader(receiver(), name, &miss);
657 DCHECK(holder()->HasFastProperties());
658 }
659
660 GenerateStoreTransition(transition, name, receiver(), this->name(), value(),
661 scratch1(), scratch2(), scratch3(), &miss, &slow);
662
663 GenerateRestoreName(&miss, name);
664 TailCallBuiltin(masm(), MissBuiltin(kind()));
665
666 GenerateRestoreName(&slow, name);
667 TailCallBuiltin(masm(), SlowBuiltin(kind()));
668 return GetCode(kind(), Code::FAST, name);
669 }
670
671
672 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
673 Label miss;
674 GenerateStoreField(it, value(), &miss);
675 __ bind(&miss);
676 TailCallBuiltin(masm(), MissBuiltin(kind()));
677 return GetCode(kind(), Code::FAST, it->name());
678 }
679
680
681 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
682 Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) {
683 Frontend(receiver(), name);
684 GenerateStoreViaSetter(masm(), type(), receiver(), setter);
685
686 return GetCode(kind(), Code::FAST, name);
687 }
688
689
690 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
691 Handle<JSObject> object, Handle<Name> name,
692 const CallOptimization& call_optimization) {
693 Frontend(receiver(), name);
694 Register values[] = {value()};
695 GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
696 receiver(), scratch1(), true, 1, values);
697 return GetCode(kind(), Code::FAST, name);
698 }
699
700
701 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
702 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
703 ElementsKind elements_kind = receiver_map->elements_kind();
704 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
705 Handle<Code> stub;
706 if (receiver_map->has_fast_elements() ||
707 receiver_map->has_external_array_elements() ||
708 receiver_map->has_fixed_typed_array_elements()) {
709 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
710 store_mode).GetCode();
711 } else {
712 stub = StoreElementStub(isolate(), is_jsarray, elements_kind, store_mode)
713 .GetCode();
714 }
715
716 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
717
718 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
719
720 return GetCode(kind(), Code::NORMAL, factory()->empty_string());
721 }
722
723
724 #undef __
725
726
727 Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type, 368 Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type,
728 Handle<Name> name, 369 Handle<Name> name,
729 InlineCacheState state) { 370 InlineCacheState state) {
730 Code::Flags flags = 371 Code::Flags flags =
731 Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder()); 372 Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder());
732 Handle<Code> code = GetCodeWithFlags(flags, name); 373 Handle<Code> code = GetCodeWithFlags(flags, name);
733 IC::RegisterWeakMapDependency(code); 374 IC::RegisterWeakMapDependency(code);
734 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 375 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
735 return code; 376 return code;
736 } 377 }
737 378
738 379
739 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
740 Code::StubType type,
741 Handle<Name> name) {
742 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder());
743 Handle<Code> code = GetCodeWithFlags(flags, name);
744 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name));
745 return code;
746 }
747
748
749 void ElementHandlerCompiler::CompileElementHandlers(
750 MapHandleList* receiver_maps, CodeHandleList* handlers) {
751 for (int i = 0; i < receiver_maps->length(); ++i) {
752 Handle<Map> receiver_map = receiver_maps->at(i);
753 Handle<Code> cached_stub;
754
755 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
756 cached_stub = isolate()->builtins()->KeyedLoadIC_String();
757 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
758 cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
759 } else {
760 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
761 ElementsKind elements_kind = receiver_map->elements_kind();
762
763 if (IsFastElementsKind(elements_kind) ||
764 IsExternalArrayElementsKind(elements_kind) ||
765 IsFixedTypedArrayElementsKind(elements_kind)) {
766 cached_stub = LoadFastElementStub(isolate(), is_js_array, elements_kind)
767 .GetCode();
768 } else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
769 cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments();
770 } else {
771 DCHECK(elements_kind == DICTIONARY_ELEMENTS);
772 cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
773 }
774 }
775
776 handlers->Add(cached_stub);
777 }
778 }
779
780
781 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 380 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
782 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) { 381 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) {
783 // Collect MONOMORPHIC stubs for all |receiver_maps|. 382 // Collect MONOMORPHIC stubs for all |receiver_maps|.
784 CodeHandleList handlers(receiver_maps->length()); 383 CodeHandleList handlers(receiver_maps->length());
785 MapHandleList transitioned_maps(receiver_maps->length()); 384 MapHandleList transitioned_maps(receiver_maps->length());
786 for (int i = 0; i < receiver_maps->length(); ++i) { 385 for (int i = 0; i < receiver_maps->length(); ++i) {
787 Handle<Map> receiver_map(receiver_maps->at(i)); 386 Handle<Map> receiver_map(receiver_maps->at(i));
788 Handle<Code> cached_stub; 387 Handle<Code> cached_stub;
789 Handle<Map> transitioned_map = 388 Handle<Map> transitioned_map =
790 receiver_map->FindTransitionedMap(receiver_maps); 389 receiver_map->FindTransitionedMap(receiver_maps);
(...skipping 29 matching lines...) Expand all
820 } 419 }
821 420
822 Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers, 421 Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers,
823 &transitioned_maps); 422 &transitioned_maps);
824 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 423 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
825 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0)); 424 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0));
826 return code; 425 return code;
827 } 426 }
828 427
829 428
830 void ElementHandlerCompiler::GenerateStoreDictionaryElement( 429 #define __ ACCESS_MASM(masm())
831 MacroAssembler* masm) { 430
832 KeyedStoreIC::GenerateSlow(masm); 431
432 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
433 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
434 ElementsKind elements_kind = receiver_map->elements_kind();
435 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
436 Handle<Code> stub;
437 if (receiver_map->has_fast_elements() ||
438 receiver_map->has_external_array_elements() ||
439 receiver_map->has_fixed_typed_array_elements()) {
440 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
441 store_mode).GetCode();
442 } else {
443 stub = StoreElementStub(isolate(), is_jsarray, elements_kind, store_mode)
444 .GetCode();
445 }
446
447 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
448
449 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
450
451 return GetCode(kind(), Code::NORMAL, factory()->empty_string());
833 } 452 }
834 453
835 454
455 #undef __
836 } 456 }
837 } // namespace v8::internal 457 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/x64/handler-compiler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698