Commit d8f2878f authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[cleanup] Cleanup the way we visit NativeContext

this will allow to add raw fields to the native context in a pointer compression
friendly way.

This CL also adds a microtask_queue field to native context which will be used
in a follow-up CL.

Bug: v8:8238, v8:7703
Change-Id: I5ecf72dbc52e8261b694551cbc8476f967967723
Reviewed-on: https://chromium-review.googlesource.com/c/1348073
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57744}
parent 71f59a23
......@@ -130,8 +130,7 @@ class Internals {
2 *
#endif
kApiSystemPointerSize;
static const int kContextHeaderSize = 2 * kApiTaggedSize;
static const int kContextEmbedderDataIndex = 5;
static const int kNativeContextEmbedderDataOffset = 7 * kApiTaggedSize;
static const int kFullStringRepresentationMask = 0x0f;
static const int kStringEncodingMask = 0x8;
static const int kExternalTwoByteRepresentationTag = 0x02;
......@@ -275,10 +274,7 @@ class Internals {
typedef internal::Address A;
typedef internal::Internals I;
A ctx = *reinterpret_cast<const A*>(context);
int embedder_data_offset =
I::kContextHeaderSize +
(internal::kApiTaggedSize * I::kContextEmbedderDataIndex);
A embedder_data = I::ReadField<A>(ctx, embedder_data_offset);
A embedder_data = I::ReadField<A>(ctx, I::kNativeContextEmbedderDataOffset);
int value_offset =
I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
return I::ReadField<T>(embedder_data, value_offset);
......
......@@ -16,6 +16,9 @@
#include "src/objects/shared-function-info-inl.h"
#include "src/objects/template-objects.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
......@@ -218,6 +221,18 @@ Map Context::GetInitialJSArrayMap(ElementsKind kind) const {
return Map::cast(initial_js_array_map);
}
MicrotaskQueue* NativeContext::microtask_queue() const {
return reinterpret_cast<MicrotaskQueue*>(
READ_INTPTR_FIELD(this, kMicrotaskQueueOffset));
}
void NativeContext::set_microtask_queue(MicrotaskQueue* microtask_queue) {
WRITE_INTPTR_FIELD(this, kMicrotaskQueueOffset,
reinterpret_cast<intptr_t>(microtask_queue));
}
#include "src/objects/object-macros-undef.h"
} // namespace internal
} // namespace v8
......
......@@ -509,8 +509,17 @@ void Context::IncrementErrorsThrown() {
set_errors_thrown(Smi::FromInt(previous_value + 1));
}
int Context::GetErrorsThrown() { return errors_thrown()->value(); }
STATIC_ASSERT(NativeContext::kStartOfStrongFieldsOffset ==
Context::OffsetOfElementAt(0));
STATIC_ASSERT(NativeContext::kStartOfWeakFieldsOffset ==
Context::OffsetOfElementAt(NativeContext::FIRST_WEAK_SLOT));
STATIC_ASSERT(NativeContext::kMicrotaskQueueOffset ==
Context::SizeFor(NativeContext::NATIVE_CONTEXT_SLOTS));
STATIC_ASSERT(NativeContext::kSize ==
(Context::SizeFor(NativeContext::NATIVE_CONTEXT_SLOTS) +
kSystemPointerSize));
} // namespace internal
} // namespace v8
......@@ -7,11 +7,15 @@
#include "src/objects/fixed-array.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
class JSGlobalObject;
class JSGlobalProxy;
class MicrotaskQueue;
class NativeContext;
class ObjectSlot;
class RegExpMatchInfo;
......@@ -446,6 +450,8 @@ class Context : public FixedArray, public NeverReadOnlySpaceObject {
// Conversions.
static inline Context* cast(Object* context);
// TODO(ishell): eventually migrate to the offset based access instead of
// index-based.
// The default context slot layout; indices are FixedArray slot indices.
enum Field {
// These slots are in all contexts.
......@@ -471,6 +477,7 @@ class Context : public FixedArray, public NeverReadOnlySpaceObject {
FIRST_JS_ARRAY_MAP_SLOT = JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX,
MIN_CONTEXT_SLOTS = GLOBAL_PROXY_INDEX,
// This slot holds the thrown value in catch contexts.
THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
......@@ -594,7 +601,7 @@ class Context : public FixedArray, public NeverReadOnlySpaceObject {
bool* is_sloppy_function_name = nullptr);
// Code generation support.
static int SlotOffset(int index) {
static constexpr int SlotOffset(int index) {
return kHeaderSize + index * kPointerSize - kHeapObjectTag;
}
......@@ -610,10 +617,13 @@ class Context : public FixedArray, public NeverReadOnlySpaceObject {
inline Map GetInitialJSArrayMap(ElementsKind kind) const;
static const int kSize = kHeaderSize + NATIVE_CONTEXT_SLOTS * kPointerSize;
static const int kNotFound = -1;
class BodyDescriptor;
// Dispatched behavior.
DECL_PRINTER(Context)
DECL_VERIFIER(Context)
typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
private:
#ifdef DEBUG
......@@ -623,8 +633,8 @@ class Context : public FixedArray, public NeverReadOnlySpaceObject {
static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
#endif
STATIC_ASSERT(kHeaderSize == Internals::kContextHeaderSize);
STATIC_ASSERT(EMBEDDER_DATA_INDEX == Internals::kContextEmbedderDataIndex);
STATIC_ASSERT(OffsetOfElementAt(EMBEDDER_DATA_INDEX) ==
Internals::kNativeContextEmbedderDataOffset);
};
class NativeContext : public Context {
......@@ -632,12 +642,42 @@ class NativeContext : public Context {
static inline NativeContext* cast(Object* context);
// TODO(neis): Move some stuff from Context here.
// [microtask_queue]: pointer to the MicrotaskQueue object.
DECL_PRIMITIVE_ACCESSORS(microtask_queue, MicrotaskQueue*)
// Dispatched behavior.
DECL_PRINTER(NativeContext)
DECL_VERIFIER(NativeContext)
// Layout description.
#define NATIVE_CONTEXT_FIELDS_DEF(V) \
V(kStartOfTaggedFieldsOffset, 0) \
/* TODO(ishell): move definition of common context offsets to Context. */ \
V(kStartOfStrongFieldsOffset, FIRST_WEAK_SLOT* kTaggedSize) \
V(kEndOfStrongFieldsOffset, 0) \
V(kStartOfWeakFieldsOffset, \
(NATIVE_CONTEXT_SLOTS - FIRST_WEAK_SLOT) * kTaggedSize) \
V(kEndOfWeakFieldsOffset, 0) \
V(kEndOfNativeContextFieldsOffset, 0) \
V(kEndOfTaggedFieldsOffset, 0) \
/* Raw data. */ \
V(kMicrotaskQueueOffset, kSystemPointerSize) \
/* Total size. */ \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(Context::kHeaderSize, NATIVE_CONTEXT_FIELDS_DEF)
#undef NATIVE_CONTEXT_FIELDS_DEF
class BodyDescriptor;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(NativeContext);
};
typedef Context::Field ContextField;
#include "src/objects/object-macros-undef.h"
} // namespace internal
} // namespace v8
......
......@@ -1378,12 +1378,18 @@ Handle<Symbol> Factory::NewPrivateNameSymbol() {
}
Handle<NativeContext> Factory::NewNativeContext() {
Handle<NativeContext> context = NewFixedArrayWithMap<NativeContext>(
RootIndex::kNativeContextMap, Context::NATIVE_CONTEXT_SLOTS, TENURED);
Map map = *native_context_map();
HeapObject* result =
AllocateRawWithImmortalMap(map->instance_size(), TENURED, map);
Handle<NativeContext> context(NativeContext::cast(result), isolate());
context->set_length(NativeContext::NATIVE_CONTEXT_SLOTS);
MemsetPointer(ObjectSlot(context->address() + NativeContext::kHeaderSize),
*undefined_value(), NativeContext::NATIVE_CONTEXT_SLOTS);
context->set_native_context(*context);
context->set_errors_thrown(Smi::zero());
context->set_math_random_index(Smi::zero());
context->set_serialized_objects(*empty_fixed_array());
context->set_microtask_queue(nullptr);
return context;
}
......
......@@ -52,7 +52,7 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map map,
map, ConcreteVisitor::template Cast<ConsString>(object));
case kVisitNativeContext:
return visitor->VisitNativeContext(
map, ConcreteVisitor::template Cast<Context>(object));
map, ConcreteVisitor::template Cast<NativeContext>(object));
case kVisitDataObject:
return visitor->VisitDataObject(map, object);
case kVisitJSObjectFast:
......@@ -111,13 +111,13 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitShortcutCandidate(
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitNativeContext(
Map map, Context* object) {
Map map, NativeContext* object) {
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
if (!visitor->ShouldVisit(object)) return ResultType();
int size = Context::BodyDescriptor::SizeOf(map, object);
if (visitor->ShouldVisitMapPointer())
visitor->VisitMapPointer(object, object->map_slot());
Context::BodyDescriptor::IterateBody(map, object, size, visitor);
int size = NativeContext::BodyDescriptor::SizeOf(map, object);
NativeContext::BodyDescriptor::IterateBody(map, object, size, visitor);
return static_cast<ResultType>(size);
}
......@@ -179,11 +179,11 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
}
template <typename ConcreteVisitor>
int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map map,
Context* object) {
int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(
Map map, NativeContext* object) {
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
int size = Context::BodyDescriptor::SizeOf(map, object);
Context::BodyDescriptor::IterateBody(map, object, size, visitor);
int size = NativeContext::BodyDescriptor::SizeOf(map, object);
NativeContext::BodyDescriptor::IterateBody(map, object, size, visitor);
return size;
}
......
......@@ -27,6 +27,7 @@ class JSRegExp;
class JSTypedArray;
class JSWeakCell;
class JSWeakCollection;
class NativeContext;
class UncompiledDataWithoutPreParsedScope;
class UncompiledDataWithPreParsedScope;
class WasmInstanceObject;
......@@ -109,7 +110,7 @@ class HeapVisitor : public ObjectVisitor {
TYPED_VISITOR_ID_LIST(VISIT)
#undef VISIT
V8_INLINE ResultType VisitShortcutCandidate(Map map, ConsString* object);
V8_INLINE ResultType VisitNativeContext(Map map, Context* object);
V8_INLINE ResultType VisitNativeContext(Map map, NativeContext* object);
V8_INLINE ResultType VisitDataObject(Map map, HeapObject* object);
V8_INLINE ResultType VisitJSObjectFast(Map map, JSObject* object);
V8_INLINE ResultType VisitJSApiObject(Map map, JSObject* object);
......@@ -133,7 +134,7 @@ class NewSpaceVisitor : public HeapVisitor<int, ConcreteVisitor> {
// Special cases for young generation.
V8_INLINE int VisitNativeContext(Map map, Context* object);
V8_INLINE int VisitNativeContext(Map map, NativeContext* object);
V8_INLINE int VisitJSApiObject(Map map, JSObject* object);
int VisitBytecodeArray(Map map, BytecodeArray* object) {
......
......@@ -479,7 +479,7 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_VARSIZE_MAP(OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
object_boilerplate_description)
ALLOCATE_VARSIZE_MAP(NATIVE_CONTEXT_TYPE, native_context)
ALLOCATE_MAP(NATIVE_CONTEXT_TYPE, NativeContext::kSize, native_context)
roots.native_context_map()->set_visitor_id(kVisitNativeContext);
ALLOCATE_MAP(CALL_HANDLER_INFO_TYPE, CallHandlerInfo::kSize,
......
......@@ -677,24 +677,23 @@ class DataHandler::BodyDescriptor final : public BodyDescriptorBase {
}
};
class Context::BodyDescriptor final : public BodyDescriptorBase {
class NativeContext::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
return offset >= Context::kHeaderSize && offset < Context::kSize;
return offset < NativeContext::kEndOfTaggedFieldsOffset;
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject* obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, Context::kHeaderSize,
Context::kHeaderSize + FIRST_WEAK_SLOT * kPointerSize, v);
IterateCustomWeakPointers(
obj, Context::kHeaderSize + FIRST_WEAK_SLOT * kPointerSize,
Context::kSize, v);
IteratePointers(obj, NativeContext::kStartOfStrongFieldsOffset,
NativeContext::kEndOfStrongFieldsOffset, v);
IterateCustomWeakPointers(obj, NativeContext::kStartOfWeakFieldsOffset,
NativeContext::kEndOfWeakFieldsOffset, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
return Context::kSize;
return NativeContext::kSize;
}
};
......@@ -784,6 +783,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case EPHEMERON_HASH_TABLE_TYPE:
case SCOPE_INFO_TYPE:
case SCRIPT_CONTEXT_TABLE_TYPE:
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
case AWAIT_CONTEXT_TYPE:
case BLOCK_CONTEXT_TYPE:
case CATCH_CONTEXT_TYPE:
......@@ -791,10 +791,11 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case EVAL_CONTEXT_TYPE:
case FUNCTION_CONTEXT_TYPE:
case MODULE_CONTEXT_TYPE:
case NATIVE_CONTEXT_TYPE:
case SCRIPT_CONTEXT_TYPE:
case WITH_CONTEXT_TYPE:
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
return Op::template apply<Context::BodyDescriptor>(p1, p2, p3, p4);
case NATIVE_CONTEXT_TYPE:
return Op::template apply<NativeContext::BodyDescriptor>(p1, p2, p3, p4);
case WEAK_FIXED_ARRAY_TYPE:
return Op::template apply<WeakFixedArray::BodyDescriptor>(p1, p2, p3, p4);
case WEAK_ARRAY_LIST_TYPE:
......
......@@ -171,6 +171,8 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case FIXED_ARRAY_TYPE:
case SCOPE_INFO_TYPE:
case SCRIPT_CONTEXT_TABLE_TYPE:
FixedArray::cast(this)->FixedArrayVerify(isolate);
break;
case AWAIT_CONTEXT_TYPE:
case BLOCK_CONTEXT_TYPE:
case CATCH_CONTEXT_TYPE:
......@@ -178,10 +180,12 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case EVAL_CONTEXT_TYPE:
case FUNCTION_CONTEXT_TYPE:
case MODULE_CONTEXT_TYPE:
case NATIVE_CONTEXT_TYPE:
case SCRIPT_CONTEXT_TYPE:
case WITH_CONTEXT_TYPE:
FixedArray::cast(this)->FixedArrayVerify(isolate);
Context::cast(this)->ContextVerify(isolate);
break;
case NATIVE_CONTEXT_TYPE:
NativeContext::cast(this)->NativeContextVerify(isolate);
break;
case WEAK_FIXED_ARRAY_TYPE:
WeakFixedArray::cast(this)->WeakFixedArrayVerify(isolate);
......@@ -736,6 +740,14 @@ void FixedDoubleArray::FixedDoubleArrayVerify(Isolate* isolate) {
}
}
void Context::ContextVerify(Isolate* isolate) { FixedArrayVerify(isolate); }
void NativeContext::NativeContextVerify(Isolate* isolate) {
CHECK_EQ(length(), NativeContext::NATIVE_CONTEXT_SLOTS);
CHECK_EQ(kSize, map()->instance_size());
FixedArrayVerify(isolate);
}
void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) {
if (slot_count() == 0) {
CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), this);
......
......@@ -1491,6 +1491,7 @@ int HeapObject::SizeFromMap(Map map) const {
// Only inline the most frequent cases.
InstanceType instance_type = map->instance_type();
if (IsInRange(instance_type, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE)) {
if (instance_type == NATIVE_CONTEXT_TYPE) return NativeContext::kSize;
return FixedArray::SizeFor(
reinterpret_cast<const FixedArray*>(this)->synchronized_length());
}
......
......@@ -140,6 +140,8 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
break;
case FIXED_ARRAY_TYPE:
FixedArray::cast(this)->FixedArrayPrint(os);
break;
case AWAIT_CONTEXT_TYPE:
case BLOCK_CONTEXT_TYPE:
case CATCH_CONTEXT_TYPE:
......@@ -147,11 +149,13 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case EVAL_CONTEXT_TYPE:
case FUNCTION_CONTEXT_TYPE:
case MODULE_CONTEXT_TYPE:
case NATIVE_CONTEXT_TYPE:
case SCRIPT_CONTEXT_TYPE:
case WITH_CONTEXT_TYPE:
case SCRIPT_CONTEXT_TABLE_TYPE:
FixedArray::cast(this)->FixedArrayPrint(os);
Context::cast(this)->ContextPrint(os);
break;
case NATIVE_CONTEXT_TYPE:
NativeContext::cast(this)->NativeContextPrint(os);
break;
case HASH_TABLE_TYPE:
case ORDERED_HASH_MAP_TYPE:
......@@ -1007,6 +1011,15 @@ void FixedArray::FixedArrayPrint(std::ostream& os) {
PrintFixedArrayWithHeader(os, this, "FixedArray");
}
void Context::ContextPrint(std::ostream& os) {
PrintFixedArrayWithHeader(os, this, "Context");
}
void NativeContext::NativeContextPrint(std::ostream& os) {
PrintFixedArrayWithHeader(os, this, "NativeContext");
os << " - microtask_queue: " << microtask_queue() << "\n";
}
void ObjectHashTable::ObjectHashTablePrint(std::ostream& os) {
PrintHashTableWithHeader(os, this, "ObjectHashTable");
}
......
......@@ -3138,11 +3138,13 @@ VisitorId Map::GetVisitorId(Map map) {
case EVAL_CONTEXT_TYPE:
case FUNCTION_CONTEXT_TYPE:
case MODULE_CONTEXT_TYPE:
case NATIVE_CONTEXT_TYPE:
case SCRIPT_CONTEXT_TYPE:
case WITH_CONTEXT_TYPE:
return kVisitFixedArray;
case NATIVE_CONTEXT_TYPE:
return kVisitNativeContext;
case EPHEMERON_HASH_TABLE_TYPE:
return kVisitEphemeronHashTable;
......
......@@ -440,6 +440,7 @@ enum InstanceType : uint16_t {
EPHEMERON_HASH_TABLE_TYPE,
SCOPE_INFO_TYPE,
SCRIPT_CONTEXT_TABLE_TYPE,
// TODO(ishell): remove native context from fixed array range
AWAIT_CONTEXT_TYPE, // FIRST_CONTEXT_TYPE
BLOCK_CONTEXT_TYPE,
CATCH_CONTEXT_TYPE,
......
......@@ -207,8 +207,8 @@ consts_misc = [
'value': 'Context::EXTENSION_INDEX' },
{ 'name': 'context_min_slots',
'value': 'Context::MIN_CONTEXT_SLOTS' },
{ 'name': 'context_idx_embedder_data',
'value': 'Internals::kContextEmbedderDataIndex' },
{ 'name': 'native_context_embedder_data_offset',
'value': 'Internals::kNativeContextEmbedderDataOffset' },
{ 'name': 'namedictionaryshape_prefix_size',
......
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