Commit 01a8acb6 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[ic] Add functions for printing out handlers

Incl. random handler-related cleanups.

Change-Id: I0a80e515c44aaf57a1834ee8ffa9cd47a31ea7be
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2398518
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70155}
parent df0ea973
......@@ -29,7 +29,7 @@ template <typename ICHandler, bool fill_handler = true>
int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler,
Handle<Smi>* smi_handler,
Handle<Map> lookup_start_object_map,
Handle<JSReceiver> holder, MaybeObjectHandle data1,
MaybeObjectHandle data1,
MaybeObjectHandle maybe_data2) {
int data_size = 1;
// Holder-is-receiver case itself does not add entries unless there is an
......@@ -92,22 +92,21 @@ int InitPrototypeChecksImpl(Isolate* isolate, Handle<ICHandler> handler,
template <typename ICHandler>
int GetHandlerDataSize(Isolate* isolate, Handle<Smi>* smi_handler,
Handle<Map> lookup_start_object_map,
Handle<JSReceiver> holder, MaybeObjectHandle data1,
MaybeObjectHandle data1,
MaybeObjectHandle maybe_data2 = MaybeObjectHandle()) {
DCHECK_NOT_NULL(smi_handler);
return InitPrototypeChecksImpl<ICHandler, false>(
isolate, Handle<ICHandler>(), smi_handler, lookup_start_object_map,
holder, data1, maybe_data2);
isolate, Handle<ICHandler>(), smi_handler, lookup_start_object_map, data1,
maybe_data2);
}
template <typename ICHandler>
void InitPrototypeChecks(Isolate* isolate, Handle<ICHandler> handler,
Handle<Map> lookup_start_object_map,
Handle<JSReceiver> holder, MaybeObjectHandle data1,
MaybeObjectHandle data1,
MaybeObjectHandle maybe_data2 = MaybeObjectHandle()) {
InitPrototypeChecksImpl<ICHandler, true>(isolate, handler, nullptr,
lookup_start_object_map, holder,
data1, maybe_data2);
InitPrototypeChecksImpl<ICHandler, true>(
isolate, handler, nullptr, lookup_start_object_map, data1, maybe_data2);
}
} // namespace
......@@ -124,9 +123,8 @@ Handle<Object> LoadHandler::LoadFromPrototype(
data1 = maybe_data1;
}
int data_size = GetHandlerDataSize<LoadHandler>(isolate, &smi_handler,
lookup_start_object_map,
holder, data1, maybe_data2);
int data_size = GetHandlerDataSize<LoadHandler>(
isolate, &smi_handler, lookup_start_object_map, data1, maybe_data2);
Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(
lookup_start_object_map, isolate);
......@@ -135,7 +133,7 @@ Handle<Object> LoadHandler::LoadFromPrototype(
handler->set_smi_handler(*smi_handler);
handler->set_validity_cell(*validity_cell);
InitPrototypeChecks(isolate, handler, lookup_start_object_map, holder, data1,
InitPrototypeChecks(isolate, handler, lookup_start_object_map, data1,
maybe_data2);
return handler;
}
......@@ -145,10 +143,9 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
Handle<Map> lookup_start_object_map,
const MaybeObjectHandle& holder,
Handle<Smi> smi_handler) {
Handle<JSReceiver> end; // null handle, means full prototype chain lookup.
MaybeObjectHandle data1 = holder;
int data_size = GetHandlerDataSize<LoadHandler>(
isolate, &smi_handler, lookup_start_object_map, end, data1);
isolate, &smi_handler, lookup_start_object_map, data1);
Handle<Object> validity_cell = Map::GetOrCreatePrototypeChainValidityCell(
lookup_start_object_map, isolate);
......@@ -165,7 +162,7 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
handler->set_smi_handler(*smi_handler);
handler->set_validity_cell(*validity_cell);
InitPrototypeChecks(isolate, handler, lookup_start_object_map, end, data1);
InitPrototypeChecks(isolate, handler, lookup_start_object_map, data1);
return handler;
}
......@@ -282,7 +279,7 @@ Handle<Object> StoreHandler::StoreThroughPrototype(
}
int data_size = GetHandlerDataSize<StoreHandler>(
isolate, &smi_handler, receiver_map, holder, data1, maybe_data2);
isolate, &smi_handler, receiver_map, data1, maybe_data2);
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate);
......@@ -291,8 +288,7 @@ Handle<Object> StoreHandler::StoreThroughPrototype(
handler->set_smi_handler(*smi_handler);
handler->set_validity_cell(*validity_cell);
InitPrototypeChecks(isolate, handler, receiver_map, holder, data1,
maybe_data2);
InitPrototypeChecks(isolate, handler, receiver_map, data1, maybe_data2);
return handler;
}
......@@ -312,5 +308,233 @@ Handle<Object> StoreHandler::StoreProxy(Isolate* isolate,
MaybeObjectHandle::Weak(proxy));
}
#if defined(OBJECT_PRINT)
namespace {
void PrintSmiLoadHandler(int raw_handler, std::ostream& os) {
LoadHandler::Kind kind = LoadHandler::KindBits::decode(raw_handler);
os << "kind = ";
switch (kind) {
case LoadHandler::Kind::kElement:
os << "kElement, allow out of bounds = "
<< LoadHandler::AllowOutOfBoundsBits::decode(raw_handler)
<< ", is JSArray = " << LoadHandler::IsJsArrayBits::decode(raw_handler)
<< ", convert hole = "
<< LoadHandler::ConvertHoleBits::decode(raw_handler)
<< ", elements kind = "
<< ElementsKindToString(
LoadHandler::ElementsKindBits::decode(raw_handler));
break;
case LoadHandler::Kind::kIndexedString:
os << "kIndexedString, allow out of bounds = "
<< LoadHandler::AllowOutOfBoundsBits::decode(raw_handler);
break;
case LoadHandler::Kind::kNormal:
os << "kNormal";
break;
case LoadHandler::Kind::kGlobal:
os << "kGlobal";
break;
case LoadHandler::Kind::kField: {
CompactElementsKind compact_elements_kind =
LoadHandler::CompactElementsKindBits::decode(raw_handler);
os << "kField, is in object = "
<< LoadHandler::IsInobjectBits::decode(raw_handler)
<< ", is double = " << LoadHandler::IsDoubleBits::decode(raw_handler)
<< ", field index = "
<< LoadHandler::FieldIndexBits::decode(raw_handler)
<< ", elements kind = "
<< CompactElementsKindToString(compact_elements_kind);
break;
}
case LoadHandler::Kind::kConstantFromPrototype: {
CompactElementsKind compact_elements_kind =
LoadHandler::CompactElementsKindBits::decode(raw_handler);
os << "kConstantFromPrototype, elements kind = "
<< CompactElementsKindToString(compact_elements_kind);
break;
}
case LoadHandler::Kind::kAccessor:
os << "kAccessor, descriptor = "
<< LoadHandler::DescriptorBits::decode(raw_handler);
break;
case LoadHandler::Kind::kNativeDataProperty:
os << "kNativeDataProperty, descriptor = "
<< LoadHandler::DescriptorBits::decode(raw_handler);
break;
case LoadHandler::Kind::kApiGetter:
os << "kApiGetter";
break;
case LoadHandler::Kind::kApiGetterHolderIsPrototype:
os << "kApiGetterHolderIsPrototype";
break;
case LoadHandler::Kind::kInterceptor:
os << "kInterceptor";
break;
case LoadHandler::Kind::kSlow:
os << "kSlow";
break;
case LoadHandler::Kind::kProxy:
os << "kProxy";
break;
case LoadHandler::Kind::kNonExistent:
os << "kNonExistent";
break;
case LoadHandler::Kind::kModuleExport:
os << "kModuleExport, exports index = "
<< LoadHandler::ExportsIndexBits::decode(raw_handler);
break;
default:
UNREACHABLE();
}
}
const char* KeyedAccessStoreModeToString(KeyedAccessStoreMode mode) {
switch (mode) {
case STANDARD_STORE:
return "STANDARD_STORE";
case STORE_AND_GROW_HANDLE_COW:
return "STORE_AND_GROW_HANDLE_COW";
case STORE_IGNORE_OUT_OF_BOUNDS:
return "STORE_IGNORE_OUT_OF_BOUNDS";
case STORE_HANDLE_COW:
return "STORE_HANDLE_COW";
}
UNREACHABLE();
}
void PrintSmiStoreHandler(int raw_handler, std::ostream& os) {
StoreHandler::Kind kind = StoreHandler::KindBits::decode(raw_handler);
os << "kind = ";
switch (kind) {
case StoreHandler::Kind::kField:
case StoreHandler::Kind::kConstField: {
os << "k";
if (kind == StoreHandler::Kind::kConstField) {
os << "Const";
}
Representation representation = Representation::FromKind(
StoreHandler::RepresentationBits::decode(raw_handler));
os << "Field, descriptor = "
<< StoreHandler::DescriptorBits::decode(raw_handler)
<< ", is in object = "
<< StoreHandler::IsInobjectBits::decode(raw_handler)
<< ", representation = " << representation.Mnemonic()
<< ", field index = "
<< StoreHandler::FieldIndexBits::decode(raw_handler);
break;
}
case StoreHandler::Kind::kAccessor:
os << "kAccessor, descriptor = "
<< StoreHandler::DescriptorBits::decode(raw_handler);
break;
case StoreHandler::Kind::kNativeDataProperty:
os << "kNativeDataProperty, descriptor = "
<< StoreHandler::DescriptorBits::decode(raw_handler);
break;
case StoreHandler::Kind::kApiSetter:
os << "kApiSetter";
break;
case StoreHandler::Kind::kApiSetterHolderIsPrototype:
os << "kApiSetterHolderIsPrototype";
break;
case StoreHandler::Kind::kGlobalProxy:
os << "kGlobalProxy";
break;
case StoreHandler::Kind::kNormal:
os << "kNormal";
break;
case StoreHandler::Kind::kInterceptor:
os << "kInterceptor";
break;
case StoreHandler::Kind::kSlow: {
KeyedAccessStoreMode keyed_access_store_mode =
StoreHandler::KeyedAccessStoreModeBits::decode(raw_handler);
os << "kSlow, keyed access store mode = "
<< KeyedAccessStoreModeToString(keyed_access_store_mode);
break;
}
case StoreHandler::Kind::kProxy:
os << "kProxy";
break;
default:
UNREACHABLE();
}
}
} // namespace
// static
void LoadHandler::PrintHandler(Object handler, std::ostream& os) {
DisallowHeapAllocation no_gc;
if (handler.IsSmi()) {
int raw_handler = handler.ToSmi().value();
os << "LoadHandler(Smi)(";
PrintSmiLoadHandler(raw_handler, os);
os << ")" << std::endl;
} else {
LoadHandler load_handler = LoadHandler::cast(handler);
int raw_handler = load_handler.smi_handler().ToSmi().value();
os << "LoadHandler(do access check on lookup start object = "
<< DoAccessCheckOnLookupStartObjectBits::decode(raw_handler)
<< ", lookup on lookup start object = "
<< LookupOnLookupStartObjectBits::decode(raw_handler) << ", ";
PrintSmiLoadHandler(raw_handler, os);
DCHECK_GE(load_handler.data_field_count(), 1);
os << ", data1 = ";
load_handler.data1().ShortPrint(os);
if (load_handler.data_field_count() >= 2) {
os << ", data2 = ";
load_handler.data2().ShortPrint(os);
}
if (load_handler.data_field_count() >= 3) {
os << ", data3 = ";
load_handler.data3().ShortPrint(os);
}
os << ", validity cell = ";
load_handler.validity_cell().ShortPrint(os);
os << ")" << std::endl;
}
}
void StoreHandler::PrintHandler(Object handler, std::ostream& os) {
DisallowHeapAllocation no_gc;
if (handler.IsSmi()) {
int raw_handler = handler.ToSmi().value();
os << "StoreHandler(Smi)(";
PrintSmiStoreHandler(raw_handler, os);
os << ")" << std::endl;
} else {
os << "StoreHandler(";
StoreHandler store_handler = StoreHandler::cast(handler);
if (store_handler.smi_handler().IsCode()) {
Code code = Code::cast(store_handler.smi_handler());
os << "builtin = ";
code.ShortPrint(os);
} else {
int raw_handler = store_handler.smi_handler().ToSmi().value();
os << "do access check on lookup start object = "
<< DoAccessCheckOnLookupStartObjectBits::decode(raw_handler)
<< ", lookup on lookup start object = "
<< LookupOnLookupStartObjectBits::decode(raw_handler) << ", ";
PrintSmiStoreHandler(raw_handler, os);
}
DCHECK_GE(store_handler.data_field_count(), 1);
os << ", data1 = ";
store_handler.data1().ShortPrint(os);
if (store_handler.data_field_count() >= 2) {
os << ", data2 = ";
store_handler.data2().ShortPrint(os);
}
if (store_handler.data_field_count() >= 3) {
os << ", data3 = ";
store_handler.data3().ShortPrint(os);
}
os << ", validity cell = ";
store_handler.validity_cell().ShortPrint(os);
os << ")" << std::endl;
}
}
#endif // defined(OBJECT_PRINT)
} // namespace internal
} // namespace v8
......@@ -63,7 +63,7 @@ class LoadHandler final : public DataHandler {
DoAccessCheckOnLookupStartObjectBits::Next<bool, 1>;
//
// Encoding when KindBits contains kForConstants.
// Encoding when KindBits contains kAccessor or kNativeDataProperty.
//
// Index of a value entry in the descriptor array.
......@@ -183,6 +183,10 @@ class LoadHandler final : public DataHandler {
// Decodes the KeyedAccessLoadMode from a {handler}.
static KeyedAccessLoadMode GetKeyedAccessLoadMode(MaybeObject handler);
#if defined(OBJECT_PRINT)
static void PrintHandler(Object handler, std::ostream& os);
#endif // defined(OBJECT_PRINT)
OBJECT_CONSTRUCTORS(LoadHandler, DataHandler);
};
......@@ -197,7 +201,6 @@ class StoreHandler final : public DataHandler {
DECL_VERIFIER(StoreHandler)
enum Kind {
kElement,
kField,
kConstField,
kAccessor,
......@@ -224,28 +227,20 @@ class StoreHandler final : public DataHandler {
using LookupOnLookupStartObjectBits =
DoAccessCheckOnLookupStartObjectBits::Next<bool, 1>;
// Applicable to kField, kTransitionToField and kTransitionToConstant
// kinds.
// Applicable to kField, kAccessor and kNativeDataProperty.
// Index of a value entry in the descriptor array.
using DescriptorBits =
LookupOnLookupStartObjectBits::Next<unsigned, kDescriptorIndexBitCount>;
//
// Encodes the bits when StoreSlow contains KeyedAccessStoreMode.
// Encoding when KindBits contains kStoreSlow.
//
using KeyedAccessStoreModeBits =
DescriptorBits::Next<KeyedAccessStoreMode, 2>;
//
// Encoding when KindBits contains kTransitionToConstant.
//
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorBits::kLastUsedBit < kSmiValueSize);
LookupOnLookupStartObjectBits::Next<KeyedAccessStoreMode, 2>;
//
// Encoding when KindBits contains kField or kTransitionToField.
// Encoding when KindBits contains kField.
//
using IsInobjectBits = DescriptorBits::Next<bool, 1>;
using RepresentationBits = IsInobjectBits::Next<Representation::Kind, 3>;
......@@ -313,6 +308,10 @@ class StoreHandler final : public DataHandler {
// Decodes the KeyedAccessStoreMode from a {handler}.
static KeyedAccessStoreMode GetKeyedAccessStoreMode(MaybeObject handler);
#if defined(OBJECT_PRINT)
static void PrintHandler(Object handler, std::ostream& os);
#endif // defined(OBJECT_PRINT)
private:
static inline Handle<Smi> StoreField(Isolate* isolate, Kind kind,
int descriptor, FieldIndex field_index,
......
......@@ -115,6 +115,13 @@ const char* ElementsKindToString(ElementsKind kind) {
}
}
const char* CompactElementsKindToString(CompactElementsKind kind) {
if (kind == CompactElementsKind::NON_COMPACT_ELEMENTS_KIND) {
return "NON_COMPACT_ELEMENTS_KIND";
}
return ElementsKindToString(static_cast<ElementsKind>(kind));
}
const ElementsKind kFastElementsKindSequence[kFastElementsKindCount] = {
PACKED_SMI_ELEMENTS, // 0
HOLEY_SMI_ELEMENTS, // 1
......
......@@ -371,6 +371,8 @@ inline CompactElementsKind ToCompactElementsKind(ElementsKind kind) {
return CompactElementsKind::NON_COMPACT_ELEMENTS_KIND;
}
const char* CompactElementsKindToString(CompactElementsKind kind);
} // namespace internal
} // namespace v8
......
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