diff options
Diffstat (limited to 'chromium/v8/src/ic/accessor-assembler.cc')
-rw-r--r-- | chromium/v8/src/ic/accessor-assembler.cc | 193 |
1 files changed, 152 insertions, 41 deletions
diff --git a/chromium/v8/src/ic/accessor-assembler.cc b/chromium/v8/src/ic/accessor-assembler.cc index 1dee1303366..5e269963201 100644 --- a/chromium/v8/src/ic/accessor-assembler.cc +++ b/chromium/v8/src/ic/accessor-assembler.cc @@ -246,12 +246,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( { Comment("convert hole"); GotoIfNot(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss); - Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); - DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); - GotoIfNot( - WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), - SmiConstant(Isolate::kProtectorValid)), - miss); + GotoIf(IsArrayProtectorCellInvalid(), miss); exit_point->Return(UndefinedConstant()); } @@ -261,8 +256,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( Label constant(this), field(this), normal(this, Label::kDeferred), interceptor(this, Label::kDeferred), nonexistent(this), - accessor(this, Label::kDeferred), proxy(this, Label::kDeferred), - global(this, Label::kDeferred), module_export(this, Label::kDeferred); + accessor(this, Label::kDeferred), global(this, Label::kDeferred), + module_export(this, Label::kDeferred), proxy(this, Label::kDeferred); GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kField)), &field); GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kConstant)), @@ -370,9 +365,35 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( BIND(&proxy); { - exit_point->ReturnCallStub( - Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), - p->context, holder, p->name, p->receiver); + VARIABLE(var_index, MachineType::PointerRepresentation()); + VARIABLE(var_unique, MachineRepresentation::kTagged); + + Label if_index(this), if_unique_name(this), + to_name_failed(this, Label::kDeferred); + + if (support_elements == kSupportElements) { + TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, + &to_name_failed); + + BIND(&if_unique_name); + exit_point->ReturnCallStub( + Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), + p->context, holder, var_unique.value(), p->receiver); + + BIND(&if_index); + // TODO(mslekova): introduce TryToName that doesn't try to compute + // the intptr index value + Goto(&to_name_failed); + + BIND(&to_name_failed); + exit_point->ReturnCallRuntime(Runtime::kGetPropertyWithReceiver, + p->context, holder, p->name, p->receiver); + + } else { + exit_point->ReturnCallStub( + Builtins::CallableFor(isolate(), Builtins::kProxyGetProperty), + p->context, holder, p->name, p->receiver); + } } BIND(&global); @@ -626,10 +647,17 @@ void AccessorAssembler::HandleStoreICHandlerCase( Node* holder = p->receiver; Node* handler_word = SmiUntag(handler); - Label if_fast_smi(this), slow(this); - GotoIfNot( - WordEqual(handler_word, IntPtrConstant(StoreHandler::kStoreNormal)), - &if_fast_smi); + Label if_fast_smi(this), if_proxy(this); + + STATIC_ASSERT(StoreHandler::kStoreNormal + 1 == StoreHandler::kProxy); + STATIC_ASSERT(StoreHandler::kProxy + 1 == StoreHandler::kKindsNumber); + + Node* handler_kind = DecodeWord<StoreHandler::KindBits>(handler_word); + GotoIf(IntPtrLessThan(handler_kind, + IntPtrConstant(StoreHandler::kStoreNormal)), + &if_fast_smi); + GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kProxy)), + &if_proxy); Node* properties = LoadSlowProperties(holder); @@ -655,6 +683,9 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_fast_smi); // Handle non-transitioning field stores. HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss); + + BIND(&if_proxy); + HandleStoreToProxy(p, holder, miss, support_elements); } BIND(&if_nonsmi_handler); @@ -669,11 +700,11 @@ void AccessorAssembler::HandleStoreICHandlerCase( if (support_elements == kSupportElements) { BIND(&if_element_handler); - { HandleStoreICElementHandlerCase(p, handler, miss); } + HandleStoreICElementHandlerCase(p, handler, miss); } BIND(&if_proto_handler); - { HandleStoreICProtoHandler(p, handler, miss, support_elements); } + HandleStoreICProtoHandler(p, handler, miss, support_elements); // |handler| is a heap object. Must be code, call it. BIND(&call_handler); @@ -792,12 +823,12 @@ void AccessorAssembler::HandleStoreICProtoHandler( VARIABLE(var_transition, MachineRepresentation::kTagged); Label if_transition(this), if_transition_to_constant(this), - if_store_normal(this); + if_store_normal(this), if_proxy(this), do_store(this); BIND(&tuple_handler); { Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); var_transition.Bind(transition); - Goto(&if_transition); + Goto(&do_store); } BIND(&array_handler); @@ -815,7 +846,19 @@ void AccessorAssembler::HandleStoreICProtoHandler( LoadFixedArrayElement(handler, StoreHandler::kTransitionCellIndex); Node* transition = LoadWeakCellValue(maybe_transition_cell, miss); var_transition.Bind(transition); - Goto(&if_transition); + Goto(&do_store); + } + + BIND(&do_store); + { + Branch(SmiEqual(smi_or_code, SmiConstant(StoreHandler::kProxy)), &if_proxy, + &if_transition); + } + + BIND(&if_proxy); + { + Node* proxy = var_transition.value(); + HandleStoreToProxy(p, proxy, miss, support_elements); } BIND(&if_transition); @@ -866,9 +909,8 @@ void AccessorAssembler::HandleStoreICProtoHandler( DescriptorArray::kEntryValueIndex)); Node* descriptors = LoadMapDescriptors(transition); CSA_ASSERT( - this, - UintPtrLessThan(descriptor, - LoadAndUntagFixedArrayBaseLength(descriptors))); + this, UintPtrLessThan(descriptor, + LoadAndUntagFixedArrayBaseLength(descriptors))); Node* constant = LoadFixedArrayElement(descriptors, value_index); GotoIf(WordNotEqual(p->value, constant), miss); @@ -915,6 +957,47 @@ void AccessorAssembler::HandleStoreICProtoHandler( } } +void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p, + Node* proxy, Label* miss, + ElementSupport support_elements) { + VARIABLE(var_index, MachineType::PointerRepresentation()); + VARIABLE(var_unique, MachineRepresentation::kTagged); + VARIABLE(var_language_mode, MachineRepresentation::kTaggedSigned, + SmiConstant(STRICT)); + + Label if_index(this), if_unique_name(this), language_mode_determined(this), + to_name_failed(this, Label::kDeferred); + BranchIfStrictMode(p->vector, p->slot, &language_mode_determined); + var_language_mode.Bind(SmiConstant(SLOPPY)); + Goto(&language_mode_determined); + BIND(&language_mode_determined); + + if (support_elements == kSupportElements) { + TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, + &to_name_failed); + + BIND(&if_unique_name); + CallBuiltin(Builtins::kProxySetProperty, p->context, proxy, + var_unique.value(), p->value, p->receiver, + var_language_mode.value()); + Return(p->value); + + // The index case is handled earlier by the runtime. + BIND(&if_index); + // TODO(mslekova): introduce TryToName that doesn't try to compute + // the intptr index value + Goto(&to_name_failed); + + BIND(&to_name_failed); + TailCallRuntime(Runtime::kSetPropertyWithReceiver, p->context, proxy, + p->name, p->value, p->receiver, var_language_mode.value()); + } else { + Node* name = ToName(p->context, p->name); + TailCallBuiltin(Builtins::kProxySetProperty, p->context, proxy, name, + p->value, p->receiver, var_language_mode.value()); + } +} + void AccessorAssembler::HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder, Node* value, Node* transition, @@ -1489,6 +1572,38 @@ void AccessorAssembler::NameDictionaryNegativeLookup(Node* object, Node* name, BIND(&done); } +void AccessorAssembler::BranchIfStrictMode(Node* vector, Node* slot, + Label* if_strict) { + Node* sfi = + LoadObjectField(vector, FeedbackVector::kSharedFunctionInfoOffset); + Node* metadata = + LoadObjectField(sfi, SharedFunctionInfo::kFeedbackMetadataOffset); + Node* slot_int = SmiToWord32(slot); + + // See VectorICComputer::index(). + const int kItemsPerWord = FeedbackMetadata::VectorICComputer::kItemsPerWord; + Node* word_index = Int32Div(slot_int, Int32Constant(kItemsPerWord)); + Node* word_offset = Int32Mod(slot_int, Int32Constant(kItemsPerWord)); + Node* data = SmiToWord32(LoadFixedArrayElement( + metadata, ChangeInt32ToIntPtr(word_index), + FeedbackMetadata::kReservedIndexCount * kPointerSize, INTPTR_PARAMETERS)); + // See VectorICComputer::decode(). + const int kBitsPerItem = FeedbackMetadata::kFeedbackSlotKindBits; + Node* shift = Int32Mul(word_offset, Int32Constant(kBitsPerItem)); + const int kMask = FeedbackMetadata::VectorICComputer::kMask; + Node* kind = Word32And(Word32Shr(data, shift), Int32Constant(kMask)); + + STATIC_ASSERT(FeedbackSlotKind::kStoreGlobalSloppy <= + FeedbackSlotKind::kLastSloppyKind); + STATIC_ASSERT(FeedbackSlotKind::kStoreKeyedSloppy <= + FeedbackSlotKind::kLastSloppyKind); + STATIC_ASSERT(FeedbackSlotKind::kStoreNamedSloppy <= + FeedbackSlotKind::kLastSloppyKind); + GotoIfNot(Int32LessThanOrEqual(kind, Int32Constant(static_cast<int>( + FeedbackSlotKind::kLastSloppyKind))), + if_strict); +} + void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, Node* instance_type, Node* index, Label* slow) { @@ -2220,8 +2335,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { } } -void AccessorAssembler::StoreIC(const StoreICParameters* p, - LanguageMode language_mode) { +void AccessorAssembler::StoreIC(const StoreICParameters* p) { VARIABLE(var_handler, MachineRepresentation::kTagged); Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred), try_megamorphic(this, Label::kDeferred), @@ -2266,8 +2380,9 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p, GotoIfNot( WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)), &miss); - TailCallStub(CodeFactory::StoreIC_Uninitialized(isolate(), language_mode), - p->context, p->receiver, p->name, p->value, p->slot, + Callable stub = + Builtins::CallableFor(isolate(), Builtins::kStoreIC_Uninitialized); + TailCallStub(stub, p->context, p->receiver, p->name, p->value, p->slot, p->vector); } BIND(&miss); @@ -2277,8 +2392,7 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p, } } -void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p, - LanguageMode language_mode) { +void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { Label miss(this, Label::kDeferred); { VARIABLE(var_handler, MachineRepresentation::kTagged); @@ -2320,7 +2434,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p, WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), &try_polymorphic_name); TailCallStub( - CodeFactory::KeyedStoreIC_Megamorphic(isolate(), language_mode), + Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC_Megamorphic), p->context, p->receiver, p->name, p->value, p->slot, p->vector); } @@ -2516,7 +2630,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_Megamorphic() { KeyedLoadICGeneric(&p); } -void AccessorAssembler::GenerateStoreIC(LanguageMode language_mode) { +void AccessorAssembler::GenerateStoreIC() { typedef StoreWithVectorDescriptor Descriptor; Node* receiver = Parameter(Descriptor::kReceiver); @@ -2527,10 +2641,10 @@ void AccessorAssembler::GenerateStoreIC(LanguageMode language_mode) { Node* context = Parameter(Descriptor::kContext); StoreICParameters p(context, receiver, name, value, slot, vector); - StoreIC(&p, language_mode); + StoreIC(&p); } -void AccessorAssembler::GenerateStoreICTrampoline(LanguageMode language_mode) { +void AccessorAssembler::GenerateStoreICTrampoline() { typedef StoreDescriptor Descriptor; Node* receiver = Parameter(Descriptor::kReceiver); @@ -2540,12 +2654,11 @@ void AccessorAssembler::GenerateStoreICTrampoline(LanguageMode language_mode) { Node* context = Parameter(Descriptor::kContext); Node* vector = LoadFeedbackVectorForStub(); - Callable callable = - CodeFactory::StoreICInOptimizedCode(isolate(), language_mode); + Callable callable = Builtins::CallableFor(isolate(), Builtins::kStoreIC); TailCallStub(callable, context, receiver, name, value, slot, vector); } -void AccessorAssembler::GenerateKeyedStoreIC(LanguageMode language_mode) { +void AccessorAssembler::GenerateKeyedStoreIC() { typedef StoreWithVectorDescriptor Descriptor; Node* receiver = Parameter(Descriptor::kReceiver); @@ -2556,11 +2669,10 @@ void AccessorAssembler::GenerateKeyedStoreIC(LanguageMode language_mode) { Node* context = Parameter(Descriptor::kContext); StoreICParameters p(context, receiver, name, value, slot, vector); - KeyedStoreIC(&p, language_mode); + KeyedStoreIC(&p); } -void AccessorAssembler::GenerateKeyedStoreICTrampoline( - LanguageMode language_mode) { +void AccessorAssembler::GenerateKeyedStoreICTrampoline() { typedef StoreDescriptor Descriptor; Node* receiver = Parameter(Descriptor::kReceiver); @@ -2570,8 +2682,7 @@ void AccessorAssembler::GenerateKeyedStoreICTrampoline( Node* context = Parameter(Descriptor::kContext); Node* vector = LoadFeedbackVectorForStub(); - Callable callable = - CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); + Callable callable = Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC); TailCallStub(callable, context, receiver, name, value, slot, vector); } |