diff options
Diffstat (limited to 'chromium/v8/src/ic/handler-configuration.cc')
-rw-r--r-- | chromium/v8/src/ic/handler-configuration.cc | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/chromium/v8/src/ic/handler-configuration.cc b/chromium/v8/src/ic/handler-configuration.cc index e5ddf06d64a..b294c864a94 100644 --- a/chromium/v8/src/ic/handler-configuration.cc +++ b/chromium/v8/src/ic/handler-configuration.cc @@ -232,41 +232,59 @@ Handle<Object> StoreHandler::StoreElementTransition( Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, Handle<Map> receiver_map, Handle<JSObject> holder, - Handle<Map> transition, + Handle<HeapObject> transition, Handle<Name> name) { - Handle<Object> smi_handler; - if (transition->is_dictionary_map()) { - smi_handler = StoreNormal(isolate); - } else { - int descriptor = transition->LastAdded(); - Handle<DescriptorArray> descriptors(transition->instance_descriptors()); - PropertyDetails details = descriptors->GetDetails(descriptor); - Representation representation = details.representation(); - DCHECK(!representation.IsNone()); + Handle<Smi> smi_handler; + Handle<WeakCell> transition_cell; + + if (transition->IsMap()) { + Handle<Map> transition_map = Handle<Map>::cast(transition); + if (transition_map->is_dictionary_map()) { + smi_handler = StoreNormal(isolate); + } else { + int descriptor = transition_map->LastAdded(); + Handle<DescriptorArray> descriptors( + transition_map->instance_descriptors()); + PropertyDetails details = descriptors->GetDetails(descriptor); + Representation representation = details.representation(); + DCHECK(!representation.IsNone()); - // Declarative handlers don't support access checks. - DCHECK(!transition->is_access_check_needed()); + // Declarative handlers don't support access checks. + DCHECK(!transition_map->is_access_check_needed()); - DCHECK_EQ(kData, details.kind()); - if (details.location() == kDescriptor) { - smi_handler = TransitionToConstant(isolate, descriptor); + DCHECK_EQ(kData, details.kind()); + if (details.location() == kDescriptor) { + smi_handler = TransitionToConstant(isolate, descriptor); + } else { + DCHECK_EQ(kField, details.location()); + bool extend_storage = Map::cast(transition_map->GetBackPointer()) + ->unused_property_fields() == 0; + + FieldIndex index = + FieldIndex::ForDescriptor(*transition_map, descriptor); + smi_handler = TransitionToField(isolate, descriptor, index, + representation, extend_storage); + } + } + // |holder| is either a receiver if the property is non-existent or + // one of the prototypes. + DCHECK(!holder.is_null()); + bool is_nonexistent = holder->map() == transition_map->GetBackPointer(); + if (is_nonexistent) holder = Handle<JSObject>::null(); + transition_cell = Map::WeakCellForMap(transition_map); + + } else { + DCHECK(transition->IsPropertyCell()); + if (receiver_map->IsJSGlobalObjectMap()) { + // TODO(ishell): this must be handled by StoreGlobalIC once it's finished. + return StoreGlobal(isolate, Handle<PropertyCell>::cast(transition)); } else { - DCHECK_EQ(kField, details.location()); - bool extend_storage = - Map::cast(transition->GetBackPointer())->unused_property_fields() == - 0; - - FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor); - smi_handler = TransitionToField(isolate, descriptor, index, - representation, extend_storage); + DCHECK(receiver_map->IsJSGlobalProxyMap()); + smi_handler = StoreGlobalProxy(isolate); + transition_cell = isolate->factory()->NewWeakCell(transition); } } - // |holder| is either a receiver if the property is non-existent or - // one of the prototypes. - DCHECK(!holder.is_null()); - bool is_nonexistent = holder->map() == transition->GetBackPointer(); - if (is_nonexistent) holder = Handle<JSObject>::null(); int checks_count = GetPrototypeCheckCount(isolate, receiver_map, holder, name); @@ -274,6 +292,12 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, DCHECK_LE(0, checks_count); DCHECK(!receiver_map->IsJSGlobalObjectMap()); + if (receiver_map->is_access_check_needed()) { + DCHECK(!receiver_map->is_dictionary_map()); + DCHECK_LE(1, checks_count); // For native context. + smi_handler = EnableAccessCheckOnReceiver(isolate, smi_handler); + } + Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); if (validity_cell.is_null()) { @@ -281,8 +305,6 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, validity_cell = handle(Smi::kZero, isolate); } - Handle<WeakCell> transition_cell = Map::WeakCellForMap(transition); - Factory* factory = isolate->factory(); if (checks_count == 0) { return factory->NewTuple3(transition_cell, smi_handler, validity_cell, @@ -292,19 +314,25 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED)); handler_array->set(kSmiHandlerIndex, *smi_handler); handler_array->set(kValidityCellIndex, *validity_cell); - handler_array->set(kTransitionCellIndex, *transition_cell); + handler_array->set(kTransitionMapOrHolderCellIndex, *transition_cell); InitPrototypeChecks(isolate, receiver_map, holder, name, handler_array, kFirstPrototypeIndex); return handler_array; } // static +Handle<Object> StoreHandler::StoreGlobal(Isolate* isolate, + Handle<PropertyCell> cell) { + return isolate->factory()->NewWeakCell(cell); +} + +// static Handle<Object> StoreHandler::StoreProxy(Isolate* isolate, Handle<Map> receiver_map, Handle<JSProxy> proxy, Handle<JSReceiver> receiver, Handle<Name> name) { - Handle<Object> smi_handler = StoreProxy(isolate); + Handle<Smi> smi_handler = StoreProxy(isolate); if (receiver.is_identical_to(proxy)) return smi_handler; @@ -312,6 +340,12 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate, DCHECK_LE(0, checks_count); + if (receiver_map->is_access_check_needed()) { + DCHECK(!receiver_map->is_dictionary_map()); + DCHECK_LE(1, checks_count); // For native context. + smi_handler = EnableAccessCheckOnReceiver(isolate, smi_handler); + } + Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); if (validity_cell.is_null()) { @@ -329,7 +363,7 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate, factory->NewFixedArray(kFirstPrototypeIndex + checks_count, TENURED)); handler_array->set(kSmiHandlerIndex, *smi_handler); handler_array->set(kValidityCellIndex, *validity_cell); - handler_array->set(kTransitionCellIndex, *holder_cell); + handler_array->set(kTransitionMapOrHolderCellIndex, *holder_cell); InitPrototypeChecks(isolate, receiver_map, proxy, name, handler_array, kFirstPrototypeIndex); return handler_array; |