Commit f1783617 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[ic] Make transition-code unaware of handler encodings

Bug: 
Change-Id: I6894c097a994527b5e749527966c5de6c42d964b
Reviewed-on: https://chromium-review.googlesource.com/668405
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48195}
parent aaebbbaa
...@@ -182,19 +182,24 @@ Handle<Smi> StoreHandler::TransitionToConstant(Isolate* isolate, ...@@ -182,19 +182,24 @@ Handle<Smi> StoreHandler::TransitionToConstant(Isolate* isolate,
} }
// static // static
WeakCell* StoreHandler::GetTuple3TransitionCell(Object* tuple3_handler) { WeakCell* StoreHandler::GetTransitionCell(Object* handler) {
STATIC_ASSERT(kTransitionCellOffset == Tuple3::kValue1Offset); if (handler->IsTuple3()) {
WeakCell* cell = WeakCell::cast(Tuple3::cast(tuple3_handler)->value1()); STATIC_ASSERT(kTransitionCellOffset == Tuple3::kValue1Offset);
WeakCell* cell = WeakCell::cast(Tuple3::cast(handler)->value1());
DCHECK(!cell->cleared());
return cell;
}
DCHECK(handler->IsFixedArray());
WeakCell* cell =
WeakCell::cast(FixedArray::cast(handler)->get(kTransitionCellIndex));
DCHECK(!cell->cleared()); DCHECK(!cell->cleared());
return cell; return cell;
} }
// static // static
WeakCell* StoreHandler::GetArrayTransitionCell(Object* array_handler) { bool StoreHandler::IsHandler(Object* maybe_handler) {
WeakCell* cell = WeakCell::cast( return maybe_handler->IsFixedArray() || maybe_handler->IsTuple3();
FixedArray::cast(array_handler)->get(kTransitionCellIndex));
DCHECK(!cell->cleared());
return cell;
} }
} // namespace internal } // namespace internal
......
...@@ -209,34 +209,6 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate, ...@@ -209,34 +209,6 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
return handler_array; return handler_array;
} }
// |name| can be nullptr if no name/details check needs to be performed.
Object* StoreHandler::ValidTuple3HandlerOrNull(Object* handler, Name* name,
Handle<Map>* out_transition) {
DCHECK(handler->IsTuple3());
// Step 1: Check validity cell.
STATIC_ASSERT(kValidityCellOffset == Tuple3::kValue3Offset);
Object* raw_validity_cell = Tuple3::cast(handler)->value3();
Smi* valid = Smi::FromInt(Map::kPrototypeChainValid);
// |raw_valitity_cell| can be Smi::kZero if no validity cell is required
// (which counts as valid).
if (raw_validity_cell->IsCell() &&
Cell::cast(raw_validity_cell)->value() != valid) {
return nullptr;
}
// Step 2 (optional): Check transition key.
WeakCell* target_cell = GetTuple3TransitionCell(handler);
if (name != nullptr) {
if (!TransitionsAccessor::IsMatchingMap(target_cell, name, kData, NONE)) {
return nullptr;
}
}
// Step 3: Check if the transition target is deprecated.
Map* transition = Map::cast(target_cell->value());
if (transition->is_deprecated()) return nullptr;
*out_transition = handle(transition);
return handler;
}
// static // static
Handle<Object> StoreHandler::StoreElementTransition( Handle<Object> StoreHandler::StoreElementTransition(
Isolate* isolate, Handle<Map> receiver_map, Handle<Map> transition, Isolate* isolate, Handle<Map> receiver_map, Handle<Map> transition,
...@@ -363,44 +335,67 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate, ...@@ -363,44 +335,67 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate,
return handler_array; return handler_array;
} }
Object* StoreHandler::ValidFixedArrayHandlerOrNull( Object* StoreHandler::ValidHandlerOrNull(Object* raw_handler, Name* name,
Object* raw_handler, Name* name, Handle<Map>* out_transition) { Handle<Map>* out_transition) {
DCHECK(raw_handler->IsFixedArray()); STATIC_ASSERT(kValidityCellOffset == Tuple3::kValue3Offset);
FixedArray* handler = FixedArray::cast(raw_handler);
// Step 1: Check validity cell. Smi* valid = Smi::FromInt(Map::kPrototypeChainValid);
Object* value = Cell::cast(handler->get(kValidityCellIndex))->value();
if (value != Smi::FromInt(Map::kPrototypeChainValid)) return nullptr; if (raw_handler->IsTuple3()) {
// Step 2: Check transition key. // Check validity cell.
WeakCell* target_cell = GetArrayTransitionCell(handler); Tuple3* handler = Tuple3::cast(raw_handler);
if (!TransitionsAccessor::IsMatchingMap(target_cell, name, kData, NONE)) {
return nullptr; Object* raw_validity_cell = handler->value3();
} // |raw_valitity_cell| can be Smi::kZero if no validity cell is required
// Step 3: Check prototypes. // (which counts as valid).
Heap* heap = handler->GetHeap(); if (raw_validity_cell->IsCell() &&
Isolate* isolate = heap->isolate(); Cell::cast(raw_validity_cell)->value() != valid) {
Handle<Name> name_handle(name, isolate); return nullptr;
for (int i = kFirstPrototypeIndex; i < handler->length(); i++) { }
// This mirrors AccessorAssembler::CheckPrototype.
WeakCell* prototype_cell = WeakCell::cast(handler->get(i)); } else {
if (prototype_cell->cleared()) return nullptr; DCHECK(raw_handler->IsFixedArray());
HeapObject* maybe_prototype = HeapObject::cast(prototype_cell->value()); FixedArray* handler = FixedArray::cast(raw_handler);
if (maybe_prototype->IsPropertyCell()) {
Object* value = PropertyCell::cast(maybe_prototype)->value(); // Check validity cell.
if (value != heap->the_hole_value()) return nullptr; Object* value = Cell::cast(handler->get(kValidityCellIndex))->value();
} else { if (value != valid) return nullptr;
DCHECK(maybe_prototype->map()->is_dictionary_map());
// Do a negative dictionary lookup. // Check prototypes.
NameDictionary* dict = Heap* heap = handler->GetHeap();
JSObject::cast(maybe_prototype)->property_dictionary(); Isolate* isolate = heap->isolate();
int number = dict->FindEntry(isolate, name_handle); Handle<Name> name_handle(name, isolate);
if (number != NameDictionary::kNotFound) return nullptr; for (int i = kFirstPrototypeIndex; i < handler->length(); i++) {
// This mirrors AccessorAssembler::CheckPrototype.
WeakCell* prototype_cell = WeakCell::cast(handler->get(i));
if (prototype_cell->cleared()) return nullptr;
HeapObject* maybe_prototype = HeapObject::cast(prototype_cell->value());
if (maybe_prototype->IsPropertyCell()) {
Object* value = PropertyCell::cast(maybe_prototype)->value();
if (value != heap->the_hole_value()) return nullptr;
} else {
DCHECK(maybe_prototype->map()->is_dictionary_map());
// Do a negative dictionary lookup.
NameDictionary* dict =
JSObject::cast(maybe_prototype)->property_dictionary();
int number = dict->FindEntry(isolate, name_handle);
if (number != NameDictionary::kNotFound) {
PropertyDetails details = dict->DetailsAt(number);
if (details.IsReadOnly() || details.kind() == kAccessor) {
return nullptr;
}
break;
}
}
} }
} }
// Step 4: Check if the transition target is deprecated.
// Check if the transition target is deprecated.
WeakCell* target_cell = GetTransitionCell(raw_handler);
Map* transition = Map::cast(target_cell->value()); Map* transition = Map::cast(target_cell->value());
if (transition->is_deprecated()) return nullptr; if (transition->is_deprecated()) return nullptr;
*out_transition = handle(transition); *out_transition = handle(transition);
return handler; return raw_handler;
} }
} // namespace internal } // namespace internal
......
...@@ -189,6 +189,8 @@ class StoreHandler { ...@@ -189,6 +189,8 @@ class StoreHandler {
enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged }; enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged };
static inline bool IsHandler(Object* maybe_handler);
// Applicable to kStoreField, kTransitionToField and kTransitionToConstant // Applicable to kStoreField, kTransitionToField and kTransitionToConstant
// kinds. // kinds.
...@@ -223,9 +225,9 @@ class StoreHandler { ...@@ -223,9 +225,9 @@ class StoreHandler {
static const int kSmiHandlerOffset = Tuple3::kValue2Offset; static const int kSmiHandlerOffset = Tuple3::kValue2Offset;
static const int kValidityCellOffset = Tuple3::kValue3Offset; static const int kValidityCellOffset = Tuple3::kValue3Offset;
static inline WeakCell* GetTuple3TransitionCell(Object* tuple3_handler); static inline WeakCell* GetTransitionCell(Object* handler);
static Object* ValidTuple3HandlerOrNull(Object* handler, Name* name, static Object* ValidHandlerOrNull(Object* handler, Name* name,
Handle<Map>* out_transition); Handle<Map>* out_transition);
// The layout of an array handler representing a transitioning store // The layout of an array handler representing a transitioning store
// when prototype chain checks include non-existing lookups and access checks. // when prototype chain checks include non-existing lookups and access checks.
...@@ -234,10 +236,6 @@ class StoreHandler { ...@@ -234,10 +236,6 @@ class StoreHandler {
static const int kTransitionCellIndex = 2; static const int kTransitionCellIndex = 2;
static const int kFirstPrototypeIndex = 3; static const int kFirstPrototypeIndex = 3;
static inline WeakCell* GetArrayTransitionCell(Object* array_handler);
static Object* ValidFixedArrayHandlerOrNull(Object* raw_handler, Name* name,
Handle<Map>* out_transition);
// Creates a Smi-handler for storing a field to fast object. // Creates a Smi-handler for storing a field to fast object.
static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor, static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor,
FieldIndex field_index, FieldIndex field_index,
......
...@@ -1738,11 +1738,8 @@ void TransitionsAccessor::PrintTransitions(std::ostream& os) { // NOLINT ...@@ -1738,11 +1738,8 @@ void TransitionsAccessor::PrintTransitions(std::ostream& os) { // NOLINT
case kWeakCell: case kWeakCell:
cell = GetTargetCell<kWeakCell>(); cell = GetTargetCell<kWeakCell>();
break; break;
case kTuple3Handler: case kHandler:
cell = GetTargetCell<kTuple3Handler>(); cell = GetTargetCell<kHandler>();
break;
case kFixedArrayHandler:
cell = GetTargetCell<kFixedArrayHandler>();
break; break;
case kFullTransitionArray: case kFullTransitionArray:
return transitions()->Print(os); return transitions()->Print(os);
......
...@@ -18,10 +18,8 @@ WeakCell* TransitionsAccessor::GetTargetCell() { ...@@ -18,10 +18,8 @@ WeakCell* TransitionsAccessor::GetTargetCell() {
if (target_cell_ != nullptr) return target_cell_; if (target_cell_ != nullptr) return target_cell_;
if (enc == kWeakCell) { if (enc == kWeakCell) {
target_cell_ = WeakCell::cast(raw_transitions_); target_cell_ = WeakCell::cast(raw_transitions_);
} else if (enc == kTuple3Handler) { } else if (enc == kHandler) {
target_cell_ = StoreHandler::GetTuple3TransitionCell(raw_transitions_); target_cell_ = StoreHandler::GetTransitionCell(raw_transitions_);
} else if (enc == kFixedArrayHandler) {
target_cell_ = StoreHandler::GetArrayTransitionCell(raw_transitions_);
} else { } else {
UNREACHABLE(); UNREACHABLE();
} }
...@@ -84,11 +82,8 @@ Name* TransitionsAccessor::GetKey(int transition_number) { ...@@ -84,11 +82,8 @@ Name* TransitionsAccessor::GetKey(int transition_number) {
case kWeakCell: case kWeakCell:
cell = GetTargetCell<kWeakCell>(); cell = GetTargetCell<kWeakCell>();
break; break;
case kTuple3Handler: case kHandler:
cell = GetTargetCell<kTuple3Handler>(); cell = GetTargetCell<kHandler>();
break;
case kFixedArrayHandler:
cell = GetTargetCell<kFixedArrayHandler>();
break; break;
case kFullTransitionArray: case kFullTransitionArray:
return transitions()->GetKey(transition_number); return transitions()->GetKey(transition_number);
...@@ -119,14 +114,8 @@ PropertyDetails TransitionsAccessor::GetTargetDetails(Name* name, Map* target) { ...@@ -119,14 +114,8 @@ PropertyDetails TransitionsAccessor::GetTargetDetails(Name* name, Map* target) {
// static // static
Map* TransitionsAccessor::GetTargetFromRaw(Object* raw) { Map* TransitionsAccessor::GetTargetFromRaw(Object* raw) {
if (raw->IsWeakCell()) { if (raw->IsWeakCell()) return Map::cast(WeakCell::cast(raw)->value());
return Map::cast(WeakCell::cast(raw)->value()); return Map::cast(StoreHandler::GetTransitionCell(raw)->value());
} else if (raw->IsTuple3()) {
return Map::cast(StoreHandler::GetTuple3TransitionCell(raw)->value());
} else {
DCHECK(raw->IsFixedArray());
return Map::cast(StoreHandler::GetArrayTransitionCell(raw)->value());
}
} }
Object* TransitionArray::GetRawTarget(int transition_number) { Object* TransitionArray::GetRawTarget(int transition_number) {
...@@ -149,11 +138,8 @@ Map* TransitionsAccessor::GetTarget(int transition_number) { ...@@ -149,11 +138,8 @@ Map* TransitionsAccessor::GetTarget(int transition_number) {
case kWeakCell: case kWeakCell:
cell = GetTargetCell<kWeakCell>(); cell = GetTargetCell<kWeakCell>();
break; break;
case kTuple3Handler: case kHandler:
cell = GetTargetCell<kTuple3Handler>(); cell = GetTargetCell<kHandler>();
break;
case kFixedArrayHandler:
cell = GetTargetCell<kFixedArrayHandler>();
break; break;
case kFullTransitionArray: case kFullTransitionArray:
return transitions()->GetTarget(transition_number); return transitions()->GetTarget(transition_number);
......
...@@ -17,10 +17,8 @@ void TransitionsAccessor::Initialize() { ...@@ -17,10 +17,8 @@ void TransitionsAccessor::Initialize() {
encoding_ = kUninitialized; encoding_ = kUninitialized;
} else if (HeapObject::cast(raw_transitions_)->IsWeakCell()) { } else if (HeapObject::cast(raw_transitions_)->IsWeakCell()) {
encoding_ = kWeakCell; encoding_ = kWeakCell;
} else if (HeapObject::cast(raw_transitions_)->IsTuple3()) { } else if (StoreHandler::IsHandler(raw_transitions_)) {
encoding_ = kTuple3Handler; encoding_ = kHandler;
} else if (HeapObject::cast(raw_transitions_)->IsFixedArray()) {
encoding_ = kFixedArrayHandler;
} else if (HeapObject::cast(raw_transitions_)->IsTransitionArray()) { } else if (HeapObject::cast(raw_transitions_)->IsTransitionArray()) {
encoding_ = kFullTransitionArray; encoding_ = kFullTransitionArray;
} else { } else {
...@@ -37,10 +35,8 @@ Map* TransitionsAccessor::GetSimpleTransition() { ...@@ -37,10 +35,8 @@ Map* TransitionsAccessor::GetSimpleTransition() {
switch (encoding()) { switch (encoding()) {
case kWeakCell: case kWeakCell:
return Map::cast(GetTargetCell<kWeakCell>()->value()); return Map::cast(GetTargetCell<kWeakCell>()->value());
case kTuple3Handler: case kHandler:
return Map::cast(GetTargetCell<kTuple3Handler>()->value()); return Map::cast(GetTargetCell<kHandler>()->value());
case kFixedArrayHandler:
return Map::cast(GetTargetCell<kFixedArrayHandler>()->value());
default: default:
return nullptr; return nullptr;
} }
...@@ -51,10 +47,8 @@ bool TransitionsAccessor::HasSimpleTransitionTo(WeakCell* cell) { ...@@ -51,10 +47,8 @@ bool TransitionsAccessor::HasSimpleTransitionTo(WeakCell* cell) {
switch (encoding()) { switch (encoding()) {
case kWeakCell: case kWeakCell:
return raw_transitions_ == cell; return raw_transitions_ == cell;
case kTuple3Handler: case kHandler:
return StoreHandler::GetTuple3TransitionCell(raw_transitions_) == cell; return StoreHandler::GetTransitionCell(raw_transitions_) == cell;
case kFixedArrayHandler:
return StoreHandler::GetArrayTransitionCell(raw_transitions_) == cell;
case kPrototypeInfo: case kPrototypeInfo:
case kUninitialized: case kUninitialized:
case kFullTransitionArray: case kFullTransitionArray:
...@@ -219,8 +213,7 @@ void TransitionsAccessor::UpdateHandler(Name* name, Object* handler) { ...@@ -219,8 +213,7 @@ void TransitionsAccessor::UpdateHandler(Name* name, Object* handler) {
UNREACHABLE(); UNREACHABLE();
return; return;
case kWeakCell: case kWeakCell:
case kTuple3Handler: case kHandler:
case kFixedArrayHandler:
DCHECK_EQ(GetSimpleTransition(), GetTargetFromRaw(handler)); DCHECK_EQ(GetSimpleTransition(), GetTargetFromRaw(handler));
ReplaceTransitions(handler); ReplaceTransitions(handler);
return; return;
...@@ -243,23 +236,23 @@ Object* TransitionsAccessor::SearchHandler(Name* name, ...@@ -243,23 +236,23 @@ Object* TransitionsAccessor::SearchHandler(Name* name,
case kUninitialized: case kUninitialized:
case kWeakCell: case kWeakCell:
return nullptr; return nullptr;
case kTuple3Handler: case kHandler: {
return StoreHandler::ValidTuple3HandlerOrNull(raw_transitions_, name, Object* raw_handler = StoreHandler::ValidHandlerOrNull(
out_transition); raw_transitions_, name, out_transition);
case kFixedArrayHandler: if (raw_handler == nullptr) return raw_handler;
return StoreHandler::ValidFixedArrayHandlerOrNull(raw_transitions_, name, // Check transition key.
out_transition); WeakCell* target_cell = StoreHandler::GetTransitionCell(raw_handler);
if (!IsMatchingMap(target_cell, name, kData, NONE)) return nullptr;
return raw_handler;
}
case kFullTransitionArray: { case kFullTransitionArray: {
int transition = transitions()->Search(kData, name, NONE); int transition = transitions()->Search(kData, name, NONE);
if (transition == kNotFound) return nullptr; if (transition == kNotFound) return nullptr;
Object* raw_handler = transitions()->GetRawTarget(transition); Object* raw_handler = transitions()->GetRawTarget(transition);
if (raw_handler->IsTuple3()) { if (StoreHandler::IsHandler(raw_handler)) {
return StoreHandler::ValidTuple3HandlerOrNull(raw_handler, nullptr, return StoreHandler::ValidHandlerOrNull(raw_handler, name,
out_transition); out_transition);
}
if (raw_handler->IsFixedArray()) {
return StoreHandler::ValidFixedArrayHandlerOrNull(raw_handler, nullptr,
out_transition);
} }
return nullptr; return nullptr;
} }
...@@ -279,11 +272,8 @@ Map* TransitionsAccessor::SearchTransition(Name* name, PropertyKind kind, ...@@ -279,11 +272,8 @@ Map* TransitionsAccessor::SearchTransition(Name* name, PropertyKind kind,
case kWeakCell: case kWeakCell:
cell = GetTargetCell<kWeakCell>(); cell = GetTargetCell<kWeakCell>();
break; break;
case kTuple3Handler: case kHandler:
cell = GetTargetCell<kTuple3Handler>(); cell = GetTargetCell<kHandler>();
break;
case kFixedArrayHandler:
cell = GetTargetCell<kFixedArrayHandler>();
break; break;
case kFullTransitionArray: { case kFullTransitionArray: {
int transition = transitions()->Search(kind, name, attributes); int transition = transitions()->Search(kind, name, attributes);
...@@ -336,11 +326,8 @@ Handle<String> TransitionsAccessor::ExpectedTransitionKey() { ...@@ -336,11 +326,8 @@ Handle<String> TransitionsAccessor::ExpectedTransitionKey() {
case kWeakCell: case kWeakCell:
cell = GetTargetCell<kWeakCell>(); cell = GetTargetCell<kWeakCell>();
break; break;
case kTuple3Handler: case kHandler:
cell = GetTargetCell<kTuple3Handler>(); cell = GetTargetCell<kHandler>();
break;
case kFixedArrayHandler:
cell = GetTargetCell<kFixedArrayHandler>();
break; break;
} }
DCHECK(!cell->cleared()); DCHECK(!cell->cleared());
...@@ -499,8 +486,7 @@ int TransitionsAccessor::NumberOfTransitions() { ...@@ -499,8 +486,7 @@ int TransitionsAccessor::NumberOfTransitions() {
case kUninitialized: case kUninitialized:
return 0; return 0;
case kWeakCell: case kWeakCell:
case kTuple3Handler: case kHandler:
case kFixedArrayHandler:
return 1; return 1;
case kFullTransitionArray: case kFullTransitionArray:
return transitions()->number_of_transitions(); return transitions()->number_of_transitions();
...@@ -583,11 +569,8 @@ void TransitionsAccessor::TraverseTransitionTreeInternal( ...@@ -583,11 +569,8 @@ void TransitionsAccessor::TraverseTransitionTreeInternal(
case kWeakCell: case kWeakCell:
simple_target = Map::cast(GetTargetCell<kWeakCell>()->value()); simple_target = Map::cast(GetTargetCell<kWeakCell>()->value());
break; break;
case kTuple3Handler: case kHandler:
simple_target = Map::cast(GetTargetCell<kTuple3Handler>()->value()); simple_target = Map::cast(GetTargetCell<kHandler>()->value());
break;
case kFixedArrayHandler:
simple_target = Map::cast(GetTargetCell<kFixedArrayHandler>()->value());
break; break;
case kFullTransitionArray: { case kFullTransitionArray: {
if (transitions()->HasPrototypeTransitions()) { if (transitions()->HasPrototypeTransitions()) {
......
...@@ -124,8 +124,7 @@ class TransitionsAccessor { ...@@ -124,8 +124,7 @@ class TransitionsAccessor {
kPrototypeInfo, kPrototypeInfo,
kUninitialized, kUninitialized,
kWeakCell, kWeakCell,
kTuple3Handler, kHandler,
kFixedArrayHandler,
kFullTransitionArray, kFullTransitionArray,
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment