Allocate feedback cells in an array decoupled from other slots
This is a pre-work for allocating feedback vectors lazily. Feedback cells are required to share the feedback vectors across the different closures of the same function. Currently, they are held in the CreateClosureSlot in the feedback vector. With lazy feedback vector allocation, we may not have a feedback vector. However, we still need a place to store the feedback cells, so if feedback vector is allocated in future it can still be shared across closures. Here is the detailed design doc: https://docs.google.com/document/d/1m2PTNChrlJqw9MiwK_xEJfqbFHAgEHmgGqmIN49PaBY/edit BUG=v8:8394 Change-Id: Ib406d862b2809b1293bfecdcfcf8dea3127cb1c7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1503753 Commit-Queue: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#60147}
This commit is contained in:
parent
656254b17b
commit
4e321413d8
@ -9951,9 +9951,37 @@ TNode<Object> CodeStubAssembler::LoadFeedbackVectorUnchecked(
|
||||
SloppyTNode<JSFunction> closure) {
|
||||
TNode<FeedbackCell> feedback_cell =
|
||||
CAST(LoadObjectField(closure, JSFunction::kFeedbackCellOffset));
|
||||
TNode<Object> maybe_vector =
|
||||
LoadObjectField(feedback_cell, FeedbackCell::kValueOffset);
|
||||
return maybe_vector;
|
||||
TVARIABLE(Object, maybe_vector, UndefinedConstant());
|
||||
Label done(this);
|
||||
|
||||
// If the closure doesn't have a feedback vector allocated yet, return
|
||||
// undefined. We check the feedback cell's map instead of undefined because
|
||||
// when there is no feedback vector, the feedback cell would contain an array
|
||||
// of feedback cells.
|
||||
GotoIf(IsNoFeedbackCellMap(LoadMap(feedback_cell)), &done);
|
||||
maybe_vector = LoadObjectField(feedback_cell, FeedbackCell::kValueOffset);
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
return maybe_vector.value();
|
||||
}
|
||||
|
||||
TNode<FixedArray> CodeStubAssembler::LoadClosureFeedbackArray(
|
||||
SloppyTNode<JSFunction> closure, Label* if_undefined) {
|
||||
TNode<FeedbackCell> feedback_cell =
|
||||
CAST(LoadObjectField(closure, JSFunction::kFeedbackCellOffset));
|
||||
TNode<HeapObject> feedback_cell_value =
|
||||
CAST(LoadObjectField(feedback_cell, FeedbackCell::kValueOffset));
|
||||
// TODO(mythria): Allocate feedback cell arrays in lite mode too. In lite
|
||||
// mode, we want to allocate feedback vectors lazily. This requires that
|
||||
// feedback cell arrays are allocated always.
|
||||
GotoIf(IsUndefined(feedback_cell_value), if_undefined);
|
||||
|
||||
// Load FeedbackCellArray from feedback vector.
|
||||
TNode<FeedbackVector> vector = CAST(feedback_cell_value);
|
||||
TNode<FixedArray> feedback_cell_array = CAST(
|
||||
LoadObjectField(vector, FeedbackVector::kClosureFeedbackCellArrayOffset));
|
||||
return feedback_cell_array;
|
||||
}
|
||||
|
||||
TNode<FeedbackVector> CodeStubAssembler::LoadFeedbackVectorForStub() {
|
||||
|
@ -2851,6 +2851,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// a feedback vector associated with it.
|
||||
TNode<Object> LoadFeedbackVectorUnchecked(SloppyTNode<JSFunction> closure);
|
||||
|
||||
TNode<FixedArray> LoadClosureFeedbackArray(SloppyTNode<JSFunction> closure,
|
||||
Label* if_undefined);
|
||||
|
||||
// Update the type feedback vector.
|
||||
void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id);
|
||||
|
||||
|
@ -1510,15 +1510,15 @@ void BytecodeGraphBuilder::VisitCreateClosure() {
|
||||
SharedFunctionInfo::cast(
|
||||
bytecode_iterator().GetConstantForIndexOperand(0)),
|
||||
isolate());
|
||||
FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
|
||||
FeedbackNexus nexus(feedback_vector(), slot);
|
||||
PretenureFlag tenured =
|
||||
interpreter::CreateClosureFlags::PretenuredBit::decode(
|
||||
bytecode_iterator().GetFlagOperand(2))
|
||||
? TENURED
|
||||
: NOT_TENURED;
|
||||
const Operator* op = javascript()->CreateClosure(
|
||||
shared_info, nexus.GetFeedbackCell(),
|
||||
shared_info,
|
||||
feedback_vector()->GetClosureFeedbackCell(
|
||||
bytecode_iterator().GetIndexOperand(1)),
|
||||
handle(jsgraph()->isolate()->builtins()->builtin(Builtins::kCompileLazy),
|
||||
isolate()),
|
||||
tenured);
|
||||
|
@ -386,10 +386,10 @@ void SerializerForBackgroundCompilation::VisitCreateClosure(
|
||||
SharedFunctionInfo::cast(iterator->GetConstantForIndexOperand(0)),
|
||||
broker()->isolate());
|
||||
|
||||
FeedbackNexus nexus(environment()->function().feedback_vector,
|
||||
iterator->GetSlotOperand(1));
|
||||
Handle<Object> cell_value(nexus.GetFeedbackCell()->value(),
|
||||
broker()->isolate());
|
||||
Handle<FeedbackCell> feedback_cell =
|
||||
environment()->function().feedback_vector->GetClosureFeedbackCell(
|
||||
iterator->GetIndexOperand(1));
|
||||
Handle<Object> cell_value(feedback_cell->value(), broker()->isolate());
|
||||
|
||||
environment()->accumulator_hints().Clear();
|
||||
if (cell_value->IsFeedbackVector()) {
|
||||
|
@ -31,6 +31,9 @@ CAST_ACCESSOR(FeedbackMetadata)
|
||||
|
||||
INT32_ACCESSORS(FeedbackMetadata, slot_count, kSlotCountOffset)
|
||||
|
||||
INT32_ACCESSORS(FeedbackMetadata, closure_feedback_cell_count,
|
||||
kFeedbackCellCountOffset)
|
||||
|
||||
int32_t FeedbackMetadata::synchronized_slot_count() const {
|
||||
return base::Acquire_Load(reinterpret_cast<const base::Atomic32*>(
|
||||
FIELD_ADDR(*this, kSlotCountOffset)));
|
||||
@ -61,7 +64,6 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
case FeedbackSlotKind::kCompareOp:
|
||||
case FeedbackSlotKind::kBinaryOp:
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
return 1;
|
||||
|
||||
@ -94,6 +96,8 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
ACCESSORS(FeedbackVector, shared_function_info, SharedFunctionInfo,
|
||||
kSharedFunctionInfoOffset)
|
||||
WEAK_ACCESSORS(FeedbackVector, optimized_code_weak_or_smi, kOptimizedCodeOffset)
|
||||
ACCESSORS(FeedbackVector, closure_feedback_cell_array, FixedArray,
|
||||
kClosureFeedbackCellArrayOffset)
|
||||
INT32_ACCESSORS(FeedbackVector, length, kLengthOffset)
|
||||
INT32_ACCESSORS(FeedbackVector, invocation_count, kInvocationCountOffset)
|
||||
INT32_ACCESSORS(FeedbackVector, profiler_ticks, kProfilerTicksOffset)
|
||||
@ -155,6 +159,12 @@ MaybeObject FeedbackVector::get(int index) const {
|
||||
return RELAXED_READ_WEAK_FIELD(*this, offset);
|
||||
}
|
||||
|
||||
Handle<FeedbackCell> FeedbackVector::GetClosureFeedbackCell(int index) const {
|
||||
DCHECK_GE(index, 0);
|
||||
FixedArray cell_array = closure_feedback_cell_array();
|
||||
return handle(FeedbackCell::cast(cell_array.get(index)), GetIsolate());
|
||||
}
|
||||
|
||||
void FeedbackVector::Set(FeedbackSlot slot, MaybeObject value,
|
||||
WriteBarrierMode mode) {
|
||||
set(GetIndex(slot), value, mode);
|
||||
@ -337,7 +347,6 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
|
||||
total++;
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kCloneObject:
|
||||
break;
|
||||
|
@ -79,7 +79,9 @@ Handle<FeedbackMetadata> FeedbackMetadata::New(Isolate* isolate,
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
const int slot_count = spec == nullptr ? 0 : spec->slots();
|
||||
if (slot_count == 0) {
|
||||
const int closure_feedback_cell_count =
|
||||
spec == nullptr ? 0 : spec->closure_feedback_cells();
|
||||
if (slot_count == 0 && closure_feedback_cell_count == 0) {
|
||||
return factory->empty_feedback_metadata();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@ -95,7 +97,8 @@ Handle<FeedbackMetadata> FeedbackMetadata::New(Isolate* isolate,
|
||||
}
|
||||
#endif
|
||||
|
||||
Handle<FeedbackMetadata> metadata = factory->NewFeedbackMetadata(slot_count);
|
||||
Handle<FeedbackMetadata> metadata =
|
||||
factory->NewFeedbackMetadata(slot_count, closure_feedback_cell_count);
|
||||
|
||||
// Initialize the slots. The raw data section has already been pre-zeroed in
|
||||
// NewFeedbackMetadata.
|
||||
@ -167,8 +170,6 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
|
||||
return "CompareOp";
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
return "StoreDataPropertyInLiteral";
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
return "kCreateClosure";
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
return "Literal";
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
@ -226,11 +227,23 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
DCHECK_EQ(vector->profiler_ticks(), 0);
|
||||
DCHECK_EQ(vector->deopt_count(), 0);
|
||||
|
||||
int num_closure_feedback_cells =
|
||||
shared->feedback_metadata()->closure_feedback_cell_count();
|
||||
if (num_closure_feedback_cells != 0) {
|
||||
Handle<FixedArray> feedback_cell_array =
|
||||
factory->NewFixedArray(num_closure_feedback_cells, TENURED);
|
||||
for (int i = 0; i < num_closure_feedback_cells; i++) {
|
||||
Handle<FeedbackCell> cell =
|
||||
factory->NewNoClosuresCell(factory->undefined_value());
|
||||
feedback_cell_array->set(i, *cell);
|
||||
}
|
||||
vector->set_closure_feedback_cell_array(*feedback_cell_array);
|
||||
}
|
||||
|
||||
// Ensure we can skip the write barrier
|
||||
Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
|
||||
DCHECK_EQ(ReadOnlyRoots(isolate).uninitialized_symbol(),
|
||||
*uninitialized_sentinel);
|
||||
Handle<Oddball> undefined_value = factory->undefined_value();
|
||||
for (int i = 0; i < slot_count;) {
|
||||
FeedbackSlot slot(i);
|
||||
FeedbackSlotKind kind = shared->feedback_metadata()->GetKind(slot);
|
||||
@ -251,11 +264,6 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
case FeedbackSlotKind::kBinaryOp:
|
||||
vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
|
||||
break;
|
||||
case FeedbackSlotKind::kCreateClosure: {
|
||||
Handle<FeedbackCell> cell = factory->NewNoClosuresCell(undefined_value);
|
||||
vector->set(index, *cell);
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
|
||||
break;
|
||||
@ -464,7 +472,6 @@ bool FeedbackNexus::Clear() {
|
||||
bool feedback_updated = false;
|
||||
|
||||
switch (kind()) {
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
// We don't clear these kinds ever.
|
||||
break;
|
||||
@ -562,9 +569,6 @@ InlineCacheState FeedbackNexus::ic_state() const {
|
||||
MaybeObject feedback = GetFeedback();
|
||||
|
||||
switch (kind()) {
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
return MONOMORPHIC;
|
||||
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
if (feedback->IsSmi()) return UNINITIALIZED;
|
||||
return MONOMORPHIC;
|
||||
@ -1233,12 +1237,6 @@ ForInHint FeedbackNexus::GetForInFeedback() const {
|
||||
return ForInHintFromFeedback(feedback);
|
||||
}
|
||||
|
||||
Handle<FeedbackCell> FeedbackNexus::GetFeedbackCell() const {
|
||||
DCHECK_EQ(FeedbackSlotKind::kCreateClosure, kind());
|
||||
return handle(FeedbackCell::cast(GetFeedback()->cast<Object>()),
|
||||
vector()->GetIsolate());
|
||||
}
|
||||
|
||||
MaybeHandle<JSObject> FeedbackNexus::GetConstructorFeedback() const {
|
||||
DCHECK_EQ(kind(), FeedbackSlotKind::kInstanceOf);
|
||||
Isolate* isolate = GetIsolate();
|
||||
|
@ -50,7 +50,6 @@ enum class FeedbackSlotKind {
|
||||
kCompareOp,
|
||||
kStoreDataPropertyInLiteral,
|
||||
kTypeProfile,
|
||||
kCreateClosure,
|
||||
kLiteral,
|
||||
kForIn,
|
||||
kInstanceOf,
|
||||
@ -173,6 +172,10 @@ class FeedbackVector : public HeapObject {
|
||||
// marker defining optimization behaviour.
|
||||
DECL_ACCESSORS(optimized_code_weak_or_smi, MaybeObject)
|
||||
|
||||
// [feedback_cell_array]: The FixedArray to hold the feedback cells for any
|
||||
// closures created by this function.
|
||||
DECL_ACCESSORS(closure_feedback_cell_array, FixedArray)
|
||||
|
||||
// [length]: The length of the feedback vector (not including the header, i.e.
|
||||
// the number of feedback slots).
|
||||
DECL_INT32_ACCESSORS(length)
|
||||
@ -220,6 +223,10 @@ class FeedbackVector : public HeapObject {
|
||||
inline void set(int index, Object value,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
|
||||
// Returns the feedback cell at |index| that is used to create the
|
||||
// closure.
|
||||
inline Handle<FeedbackCell> GetClosureFeedbackCell(int index) const;
|
||||
|
||||
// Gives access to raw memory which stores the array's data.
|
||||
inline MaybeObjectSlot slots_start();
|
||||
|
||||
@ -287,6 +294,7 @@ class FeedbackVector : public HeapObject {
|
||||
/* Header fields. */ \
|
||||
V(kSharedFunctionInfoOffset, kTaggedSize) \
|
||||
V(kOptimizedCodeOffset, kTaggedSize) \
|
||||
V(kClosureFeedbackCellArrayOffset, kTaggedSize) \
|
||||
V(kLengthOffset, kInt32Size) \
|
||||
V(kInvocationCountOffset, kInt32Size) \
|
||||
V(kProfilerTicksOffset, kInt32Size) \
|
||||
@ -316,11 +324,17 @@ class FeedbackVector : public HeapObject {
|
||||
|
||||
class V8_EXPORT_PRIVATE FeedbackVectorSpec {
|
||||
public:
|
||||
explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone) {
|
||||
explicit FeedbackVectorSpec(Zone* zone)
|
||||
: slot_kinds_(zone), num_closure_feedback_cells_(0) {
|
||||
slot_kinds_.reserve(16);
|
||||
}
|
||||
|
||||
int slots() const { return static_cast<int>(slot_kinds_.size()); }
|
||||
int closure_feedback_cells() const { return num_closure_feedback_cells_; }
|
||||
|
||||
int AddFeedbackCellForCreateClosure() {
|
||||
return num_closure_feedback_cells_++;
|
||||
}
|
||||
|
||||
FeedbackSlotKind GetKind(FeedbackSlot slot) const {
|
||||
return static_cast<FeedbackSlotKind>(slot_kinds_.at(slot.ToInt()));
|
||||
@ -345,10 +359,6 @@ class V8_EXPORT_PRIVATE FeedbackVectorSpec {
|
||||
: FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
||||
}
|
||||
|
||||
FeedbackSlot AddCreateClosureSlot() {
|
||||
return AddSlot(FeedbackSlotKind::kCreateClosure);
|
||||
}
|
||||
|
||||
FeedbackSlot AddKeyedLoadICSlot() {
|
||||
return AddSlot(FeedbackSlotKind::kLoadKeyed);
|
||||
}
|
||||
@ -433,6 +443,7 @@ class V8_EXPORT_PRIVATE FeedbackVectorSpec {
|
||||
}
|
||||
|
||||
ZoneVector<unsigned char> slot_kinds_;
|
||||
unsigned int num_closure_feedback_cells_;
|
||||
|
||||
friend class SharedFeedbackSlot;
|
||||
};
|
||||
@ -467,6 +478,12 @@ class FeedbackMetadata : public HeapObject {
|
||||
// The number of slots that this metadata contains. Stored as an int32.
|
||||
DECL_INT32_ACCESSORS(slot_count)
|
||||
|
||||
// The number of feedback cells required for create closures. Stored as an
|
||||
// int32.
|
||||
// TODO(mythria): Consider using 16 bits for this and slot_count so that we
|
||||
// can save 4 bytes.
|
||||
DECL_INT32_ACCESSORS(closure_feedback_cell_count)
|
||||
|
||||
// Get slot_count using an acquire load.
|
||||
inline int32_t synchronized_slot_count() const;
|
||||
|
||||
@ -498,7 +515,8 @@ class FeedbackMetadata : public HeapObject {
|
||||
}
|
||||
|
||||
static const int kSlotCountOffset = HeapObject::kHeaderSize;
|
||||
static const int kHeaderSize = kSlotCountOffset + kInt32Size;
|
||||
static const int kFeedbackCellCountOffset = kSlotCountOffset + kInt32Size;
|
||||
static const int kHeaderSize = kFeedbackCellCountOffset + kInt32Size;
|
||||
|
||||
class BodyDescriptor;
|
||||
|
||||
@ -670,9 +688,6 @@ class FeedbackNexus final {
|
||||
typedef BitField<SpeculationMode, 0, 1> SpeculationModeField;
|
||||
typedef BitField<uint32_t, 1, 31> CallCountField;
|
||||
|
||||
// For CreateClosure ICs.
|
||||
Handle<FeedbackCell> GetFeedbackCell() const;
|
||||
|
||||
// For InstanceOf ICs.
|
||||
MaybeHandle<JSObject> GetConstructorFeedback() const;
|
||||
|
||||
|
@ -431,6 +431,8 @@ Handle<FeedbackVector> Factory::NewFeedbackVector(
|
||||
vector->set_invocation_count(0);
|
||||
vector->set_profiler_ticks(0);
|
||||
vector->set_deopt_count(0);
|
||||
vector->set_closure_feedback_cell_array(*empty_fixed_array());
|
||||
|
||||
// TODO(leszeks): Initialize based on the feedback metadata.
|
||||
MemsetTagged(ObjectSlot(vector->slots_start()), *undefined_value(), length);
|
||||
return vector;
|
||||
@ -516,6 +518,7 @@ Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(
|
||||
}
|
||||
|
||||
Handle<FeedbackMetadata> Factory::NewFeedbackMetadata(int slot_count,
|
||||
int feedback_cell_count,
|
||||
PretenureFlag tenure) {
|
||||
DCHECK_LE(0, slot_count);
|
||||
int size = FeedbackMetadata::SizeFor(slot_count);
|
||||
@ -523,6 +526,7 @@ Handle<FeedbackMetadata> Factory::NewFeedbackMetadata(int slot_count,
|
||||
AllocateRawWithImmortalMap(size, tenure, *feedback_metadata_map());
|
||||
Handle<FeedbackMetadata> data(FeedbackMetadata::cast(result), isolate());
|
||||
data->set_slot_count(slot_count);
|
||||
data->set_closure_feedback_cell_count(feedback_cell_count);
|
||||
|
||||
// Initialize the data section to 0.
|
||||
int data_size = size - FeedbackMetadata::kHeaderSize;
|
||||
|
@ -179,6 +179,7 @@ class V8_EXPORT_PRIVATE Factory {
|
||||
|
||||
// Allocates a FeedbackMedata object and zeroes the data section.
|
||||
Handle<FeedbackMetadata> NewFeedbackMetadata(int slot_count,
|
||||
int feedback_cell_count,
|
||||
PretenureFlag tenure = TENURED);
|
||||
|
||||
Handle<FrameArray> NewFrameArray(int number_of_frames,
|
||||
|
@ -616,6 +616,13 @@ void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
|
||||
|
||||
size_t calculated_size = 0;
|
||||
|
||||
// Log the feedback_cell array used for create closures.
|
||||
RecordVirtualObjectStats(
|
||||
vector, vector->closure_feedback_cell_array(),
|
||||
ObjectStats::FEEDBACK_VECTOR_CREATE_CLOSURE_ARRAY_TYPE,
|
||||
vector->closure_feedback_cell_array()->Size(),
|
||||
ObjectStats::kNoOverAllocation);
|
||||
|
||||
// Log the feedback vector's header (fixed fields).
|
||||
size_t header_size = vector->slots_start().address() - vector->address();
|
||||
stats_->RecordVirtualObjectStats(ObjectStats::FEEDBACK_VECTOR_HEADER_TYPE,
|
||||
|
@ -31,6 +31,7 @@
|
||||
V(ENUM_INDICES_CACHE_TYPE) \
|
||||
V(FEEDBACK_VECTOR_ENTRY_TYPE) \
|
||||
V(FEEDBACK_VECTOR_HEADER_TYPE) \
|
||||
V(FEEDBACK_VECTOR_CREATE_CLOSURE_ARRAY_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_CALL_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE) \
|
||||
|
@ -838,7 +838,7 @@ void Heap::CreateInitialObjects() {
|
||||
|
||||
// Allocate the empty FeedbackMetadata.
|
||||
Handle<FeedbackMetadata> empty_feedback_metadata =
|
||||
factory->NewFeedbackMetadata(0, TENURED_READ_ONLY);
|
||||
factory->NewFeedbackMetadata(0, 0, TENURED_READ_ONLY);
|
||||
set_empty_feedback_metadata(*empty_feedback_metadata);
|
||||
|
||||
// Allocate the empty script.
|
||||
|
@ -731,15 +731,14 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
||||
has_constant_pool_entry_(false) {}
|
||||
|
||||
void AddFunctionDeclaration(const AstRawString* name, FeedbackSlot slot,
|
||||
FeedbackSlot literal_slot,
|
||||
FunctionLiteral* func) {
|
||||
int feedback_cell_index, FunctionLiteral* func) {
|
||||
DCHECK(!slot.IsInvalid());
|
||||
declarations_.push_back(Declaration(name, slot, literal_slot, func));
|
||||
declarations_.push_back(Declaration(name, slot, feedback_cell_index, func));
|
||||
}
|
||||
|
||||
void AddUndefinedDeclaration(const AstRawString* name, FeedbackSlot slot) {
|
||||
DCHECK(!slot.IsInvalid());
|
||||
declarations_.push_back(Declaration(name, slot, nullptr));
|
||||
declarations_.push_back(Declaration(name, slot));
|
||||
}
|
||||
|
||||
Handle<FixedArray> AllocateDeclarations(UnoptimizedCompilationInfo* info,
|
||||
@ -765,11 +764,11 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
||||
data->set(array_index++, *declaration.name->string());
|
||||
data->set(array_index++, Smi::FromInt(declaration.slot.ToInt()));
|
||||
Object undefined_or_literal_slot;
|
||||
if (declaration.literal_slot.IsInvalid()) {
|
||||
if (declaration.feedback_cell_index_for_function == -1) {
|
||||
undefined_or_literal_slot = ReadOnlyRoots(isolate).undefined_value();
|
||||
} else {
|
||||
undefined_or_literal_slot =
|
||||
Smi::FromInt(declaration.literal_slot.ToInt());
|
||||
Smi::FromInt(declaration.feedback_cell_index_for_function);
|
||||
}
|
||||
data->set(array_index++, undefined_or_literal_slot);
|
||||
data->set(array_index++, *initial_value);
|
||||
@ -795,18 +794,23 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
||||
struct Declaration {
|
||||
Declaration() : slot(FeedbackSlot::Invalid()), func(nullptr) {}
|
||||
Declaration(const AstRawString* name, FeedbackSlot slot,
|
||||
FeedbackSlot literal_slot, FunctionLiteral* func)
|
||||
: name(name), slot(slot), literal_slot(literal_slot), func(func) {}
|
||||
Declaration(const AstRawString* name, FeedbackSlot slot,
|
||||
FunctionLiteral* func)
|
||||
int feedback_cell_index, FunctionLiteral* func)
|
||||
: name(name),
|
||||
slot(slot),
|
||||
literal_slot(FeedbackSlot::Invalid()),
|
||||
feedback_cell_index_for_function(feedback_cell_index),
|
||||
func(func) {}
|
||||
Declaration(const AstRawString* name, FeedbackSlot slot)
|
||||
: name(name),
|
||||
slot(slot),
|
||||
feedback_cell_index_for_function(-1),
|
||||
func(nullptr) {}
|
||||
|
||||
const AstRawString* name;
|
||||
FeedbackSlot slot;
|
||||
FeedbackSlot literal_slot;
|
||||
// Only valid for function declarations. Specifies the index into the
|
||||
// closure_feedback_cell array used when creating closures of this
|
||||
// function.
|
||||
int feedback_cell_index_for_function;
|
||||
FunctionLiteral* func;
|
||||
};
|
||||
ZoneVector<Declaration> declarations_;
|
||||
@ -836,51 +840,61 @@ class BytecodeGenerator::CurrentScope final {
|
||||
|
||||
class BytecodeGenerator::FeedbackSlotCache : public ZoneObject {
|
||||
public:
|
||||
enum class SlotKind {
|
||||
kStoreGlobalSloppy,
|
||||
kStoreGlobalStrict,
|
||||
kStoreNamedStrict,
|
||||
kStoreNamedSloppy,
|
||||
kLoadProperty,
|
||||
kLoadGlobalNotInsideTypeof,
|
||||
kLoadGlobalInsideTypeof,
|
||||
kClosureFeedbackCell
|
||||
};
|
||||
|
||||
explicit FeedbackSlotCache(Zone* zone) : map_(zone) {}
|
||||
|
||||
void Put(FeedbackSlotKind slot_kind, Variable* variable, FeedbackSlot slot) {
|
||||
PutImpl(slot_kind, 0, variable, slot);
|
||||
void Put(SlotKind slot_kind, Variable* variable, int slot_index) {
|
||||
PutImpl(slot_kind, 0, variable, slot_index);
|
||||
}
|
||||
void Put(FeedbackSlotKind slot_kind, AstNode* node, FeedbackSlot slot) {
|
||||
PutImpl(slot_kind, 0, node, slot);
|
||||
void Put(SlotKind slot_kind, AstNode* node, int slot_index) {
|
||||
PutImpl(slot_kind, 0, node, slot_index);
|
||||
}
|
||||
void Put(FeedbackSlotKind slot_kind, int variable_index,
|
||||
const AstRawString* name, FeedbackSlot slot) {
|
||||
PutImpl(slot_kind, variable_index, name, slot);
|
||||
void Put(SlotKind slot_kind, int variable_index, const AstRawString* name,
|
||||
int slot_index) {
|
||||
PutImpl(slot_kind, variable_index, name, slot_index);
|
||||
}
|
||||
|
||||
FeedbackSlot Get(FeedbackSlotKind slot_kind, Variable* variable) const {
|
||||
int Get(SlotKind slot_kind, Variable* variable) const {
|
||||
return GetImpl(slot_kind, 0, variable);
|
||||
}
|
||||
FeedbackSlot Get(FeedbackSlotKind slot_kind, AstNode* node) const {
|
||||
int Get(SlotKind slot_kind, AstNode* node) const {
|
||||
return GetImpl(slot_kind, 0, node);
|
||||
}
|
||||
FeedbackSlot Get(FeedbackSlotKind slot_kind, int variable_index,
|
||||
int Get(SlotKind slot_kind, int variable_index,
|
||||
const AstRawString* name) const {
|
||||
return GetImpl(slot_kind, variable_index, name);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::tuple<FeedbackSlotKind, int, const void*> Key;
|
||||
typedef std::tuple<SlotKind, int, const void*> Key;
|
||||
|
||||
void PutImpl(FeedbackSlotKind slot_kind, int index, const void* node,
|
||||
FeedbackSlot slot) {
|
||||
void PutImpl(SlotKind slot_kind, int index, const void* node,
|
||||
int slot_index) {
|
||||
Key key = std::make_tuple(slot_kind, index, node);
|
||||
auto entry = std::make_pair(key, slot);
|
||||
auto entry = std::make_pair(key, slot_index);
|
||||
map_.insert(entry);
|
||||
}
|
||||
|
||||
FeedbackSlot GetImpl(FeedbackSlotKind slot_kind, int index,
|
||||
const void* node) const {
|
||||
int GetImpl(SlotKind slot_kind, int index, const void* node) const {
|
||||
Key key = std::make_tuple(slot_kind, index, node);
|
||||
auto iter = map_.find(key);
|
||||
if (iter != map_.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
return FeedbackSlot();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ZoneMap<Key, FeedbackSlot> map_;
|
||||
ZoneMap<Key, int> map_;
|
||||
};
|
||||
|
||||
class BytecodeGenerator::IteratorRecord final {
|
||||
@ -1285,9 +1299,9 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
FeedbackSlot slot =
|
||||
GetCachedLoadGlobalICSlot(NOT_INSIDE_TYPEOF, variable);
|
||||
FeedbackSlot literal_slot = GetCachedCreateClosureSlot(decl->fun());
|
||||
int literal_index = GetCachedCreateClosureSlot(decl->fun());
|
||||
globals_builder()->AddFunctionDeclaration(variable->raw_name(), slot,
|
||||
literal_slot, decl->fun());
|
||||
literal_index, decl->fun());
|
||||
AddToEagerLiteralsIfEager(decl->fun());
|
||||
break;
|
||||
}
|
||||
@ -1895,8 +1909,7 @@ void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
expr->pretenure(), closure_scope()->is_function_scope(),
|
||||
info()->might_always_opt());
|
||||
size_t entry = builder()->AllocateDeferredConstantPoolEntry();
|
||||
FeedbackSlot slot = GetCachedCreateClosureSlot(expr);
|
||||
builder()->CreateClosure(entry, feedback_index(slot), flags);
|
||||
builder()->CreateClosure(entry, GetCachedCreateClosureSlot(expr), flags);
|
||||
function_literals_.push_back(std::make_pair(expr, entry));
|
||||
AddToEagerLiteralsIfEager(expr);
|
||||
}
|
||||
@ -2155,8 +2168,8 @@ void BytecodeGenerator::BuildInstanceMemberInitialization(Register constructor,
|
||||
void BytecodeGenerator::VisitNativeFunctionLiteral(
|
||||
NativeFunctionLiteral* expr) {
|
||||
size_t entry = builder()->AllocateDeferredConstantPoolEntry();
|
||||
FeedbackSlot slot = feedback_spec()->AddCreateClosureSlot();
|
||||
builder()->CreateClosure(entry, feedback_index(slot), NOT_TENURED);
|
||||
int index = feedback_spec()->AddFeedbackCellForCreateClosure();
|
||||
builder()->CreateClosure(entry, index, NOT_TENURED);
|
||||
native_function_literals_.push_back(std::make_pair(expr, entry));
|
||||
}
|
||||
|
||||
@ -5789,30 +5802,31 @@ int BytecodeGenerator::feedback_index(FeedbackSlot slot) const {
|
||||
|
||||
FeedbackSlot BytecodeGenerator::GetCachedLoadGlobalICSlot(
|
||||
TypeofMode typeof_mode, Variable* variable) {
|
||||
FeedbackSlotKind slot_kind =
|
||||
FeedbackSlotCache::SlotKind slot_kind =
|
||||
typeof_mode == INSIDE_TYPEOF
|
||||
? FeedbackSlotKind::kLoadGlobalInsideTypeof
|
||||
: FeedbackSlotKind::kLoadGlobalNotInsideTypeof;
|
||||
FeedbackSlot slot = feedback_slot_cache()->Get(slot_kind, variable);
|
||||
? FeedbackSlotCache::SlotKind::kLoadGlobalInsideTypeof
|
||||
: FeedbackSlotCache::SlotKind::kLoadGlobalNotInsideTypeof;
|
||||
FeedbackSlot slot(feedback_slot_cache()->Get(slot_kind, variable));
|
||||
if (!slot.IsInvalid()) {
|
||||
return slot;
|
||||
}
|
||||
slot = feedback_spec()->AddLoadGlobalICSlot(typeof_mode);
|
||||
feedback_slot_cache()->Put(slot_kind, variable, slot);
|
||||
feedback_slot_cache()->Put(slot_kind, variable, feedback_index(slot));
|
||||
return slot;
|
||||
}
|
||||
|
||||
FeedbackSlot BytecodeGenerator::GetCachedStoreGlobalICSlot(
|
||||
LanguageMode language_mode, Variable* variable) {
|
||||
FeedbackSlotKind slot_kind = is_strict(language_mode)
|
||||
? FeedbackSlotKind::kStoreGlobalStrict
|
||||
: FeedbackSlotKind::kStoreGlobalSloppy;
|
||||
FeedbackSlot slot = feedback_slot_cache()->Get(slot_kind, variable);
|
||||
FeedbackSlotCache::SlotKind slot_kind =
|
||||
is_strict(language_mode)
|
||||
? FeedbackSlotCache::SlotKind::kStoreGlobalStrict
|
||||
: FeedbackSlotCache::SlotKind::kStoreGlobalSloppy;
|
||||
FeedbackSlot slot(feedback_slot_cache()->Get(slot_kind, variable));
|
||||
if (!slot.IsInvalid()) {
|
||||
return slot;
|
||||
}
|
||||
slot = feedback_spec()->AddStoreGlobalICSlot(language_mode);
|
||||
feedback_slot_cache()->Put(slot_kind, variable, slot);
|
||||
feedback_slot_cache()->Put(slot_kind, variable, feedback_index(slot));
|
||||
return slot;
|
||||
}
|
||||
|
||||
@ -5821,18 +5835,20 @@ FeedbackSlot BytecodeGenerator::GetCachedLoadICSlot(const Expression* expr,
|
||||
if (!FLAG_ignition_share_named_property_feedback) {
|
||||
return feedback_spec()->AddLoadICSlot();
|
||||
}
|
||||
FeedbackSlotKind slot_kind = FeedbackSlotKind::kLoadProperty;
|
||||
FeedbackSlotCache::SlotKind slot_kind =
|
||||
FeedbackSlotCache::SlotKind::kLoadProperty;
|
||||
if (!expr->IsVariableProxy()) {
|
||||
return feedback_spec()->AddLoadICSlot();
|
||||
}
|
||||
const VariableProxy* proxy = expr->AsVariableProxy();
|
||||
FeedbackSlot slot =
|
||||
feedback_slot_cache()->Get(slot_kind, proxy->var()->index(), name);
|
||||
FeedbackSlot slot(
|
||||
feedback_slot_cache()->Get(slot_kind, proxy->var()->index(), name));
|
||||
if (!slot.IsInvalid()) {
|
||||
return slot;
|
||||
}
|
||||
slot = feedback_spec()->AddLoadICSlot();
|
||||
feedback_slot_cache()->Put(slot_kind, proxy->var()->index(), name, slot);
|
||||
feedback_slot_cache()->Put(slot_kind, proxy->var()->index(), name,
|
||||
feedback_index(slot));
|
||||
return slot;
|
||||
}
|
||||
|
||||
@ -5841,33 +5857,35 @@ FeedbackSlot BytecodeGenerator::GetCachedStoreICSlot(const Expression* expr,
|
||||
if (!FLAG_ignition_share_named_property_feedback) {
|
||||
return feedback_spec()->AddStoreICSlot(language_mode());
|
||||
}
|
||||
FeedbackSlotKind slot_kind = is_strict(language_mode())
|
||||
? FeedbackSlotKind::kStoreNamedStrict
|
||||
: FeedbackSlotKind::kStoreNamedSloppy;
|
||||
FeedbackSlotCache::SlotKind slot_kind =
|
||||
is_strict(language_mode())
|
||||
? FeedbackSlotCache::SlotKind::kStoreNamedStrict
|
||||
: FeedbackSlotCache::SlotKind::kStoreNamedSloppy;
|
||||
if (!expr->IsVariableProxy()) {
|
||||
return feedback_spec()->AddStoreICSlot(language_mode());
|
||||
}
|
||||
const VariableProxy* proxy = expr->AsVariableProxy();
|
||||
FeedbackSlot slot =
|
||||
feedback_slot_cache()->Get(slot_kind, proxy->var()->index(), name);
|
||||
FeedbackSlot slot(
|
||||
feedback_slot_cache()->Get(slot_kind, proxy->var()->index(), name));
|
||||
if (!slot.IsInvalid()) {
|
||||
return slot;
|
||||
}
|
||||
slot = feedback_spec()->AddStoreICSlot(language_mode());
|
||||
feedback_slot_cache()->Put(slot_kind, proxy->var()->index(), name, slot);
|
||||
feedback_slot_cache()->Put(slot_kind, proxy->var()->index(), name,
|
||||
feedback_index(slot));
|
||||
return slot;
|
||||
}
|
||||
|
||||
FeedbackSlot BytecodeGenerator::GetCachedCreateClosureSlot(
|
||||
FunctionLiteral* literal) {
|
||||
FeedbackSlotKind slot_kind = FeedbackSlotKind::kCreateClosure;
|
||||
FeedbackSlot slot = feedback_slot_cache()->Get(slot_kind, literal);
|
||||
if (!slot.IsInvalid()) {
|
||||
return slot;
|
||||
int BytecodeGenerator::GetCachedCreateClosureSlot(FunctionLiteral* literal) {
|
||||
FeedbackSlotCache::SlotKind slot_kind =
|
||||
FeedbackSlotCache::SlotKind::kClosureFeedbackCell;
|
||||
int index = feedback_slot_cache()->Get(slot_kind, literal);
|
||||
if (index != -1) {
|
||||
return index;
|
||||
}
|
||||
slot = feedback_spec()->AddCreateClosureSlot();
|
||||
feedback_slot_cache()->Put(slot_kind, literal, slot);
|
||||
return slot;
|
||||
index = feedback_spec()->AddFeedbackCellForCreateClosure();
|
||||
feedback_slot_cache()->Put(slot_kind, literal, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
FeedbackSlot BytecodeGenerator::GetDummyCompareICSlot() {
|
||||
|
@ -384,13 +384,14 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
Variable* variable);
|
||||
FeedbackSlot GetCachedStoreGlobalICSlot(LanguageMode language_mode,
|
||||
Variable* variable);
|
||||
FeedbackSlot GetCachedCreateClosureSlot(FunctionLiteral* literal);
|
||||
FeedbackSlot GetCachedLoadICSlot(const Expression* expr,
|
||||
const AstRawString* name);
|
||||
FeedbackSlot GetCachedStoreICSlot(const Expression* expr,
|
||||
const AstRawString* name);
|
||||
FeedbackSlot GetDummyCompareICSlot();
|
||||
|
||||
int GetCachedCreateClosureSlot(FunctionLiteral* literal);
|
||||
|
||||
void AddToEagerLiteralsIfEager(FunctionLiteral* literal);
|
||||
|
||||
// Checks if the visited expression is one shot, i.e executed only once. Any
|
||||
|
@ -2633,10 +2633,9 @@ IGNITION_HANDLER(CreateClosure, InterpreterAssembler) {
|
||||
|
||||
Label if_undefined(this), load_feedback_done(this);
|
||||
Variable feedback_cell(this, MachineRepresentation::kTagged);
|
||||
Node* feedback_vector = LoadFeedbackVectorUnchecked();
|
||||
|
||||
GotoIf(IsUndefined(feedback_vector), &if_undefined);
|
||||
feedback_cell.Bind(LoadFeedbackVectorSlot(feedback_vector, slot));
|
||||
TNode<FixedArray> feedback_cell_array = LoadClosureFeedbackArray(
|
||||
LoadRegister(Register::function_closure()), &if_undefined);
|
||||
feedback_cell.Bind(LoadFixedArrayElement(feedback_cell_array, slot));
|
||||
Goto(&load_feedback_done);
|
||||
|
||||
BIND(&if_undefined);
|
||||
|
@ -469,7 +469,9 @@ class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase {
|
||||
public:
|
||||
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
|
||||
return offset == kSharedFunctionInfoOffset ||
|
||||
offset == kOptimizedCodeOffset || offset >= kFeedbackSlotsOffset;
|
||||
offset == kOptimizedCodeOffset ||
|
||||
offset == kClosureFeedbackCellArrayOffset ||
|
||||
offset >= kFeedbackSlotsOffset;
|
||||
}
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
@ -477,6 +479,7 @@ class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase {
|
||||
ObjectVisitor* v) {
|
||||
IteratePointer(obj, kSharedFunctionInfoOffset, v);
|
||||
IterateMaybeWeakPointer(obj, kOptimizedCodeOffset, v);
|
||||
IteratePointer(obj, kClosureFeedbackCellArrayOffset, v);
|
||||
IterateMaybeWeakPointers(obj, kFeedbackSlotsOffset, object_size, v);
|
||||
}
|
||||
|
||||
|
@ -769,7 +769,7 @@ void NativeContext::NativeContextVerify(Isolate* isolate) {
|
||||
}
|
||||
|
||||
void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) {
|
||||
if (slot_count() == 0) {
|
||||
if (slot_count() == 0 && closure_feedback_cell_count() == 0) {
|
||||
CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), *this);
|
||||
} else {
|
||||
FeedbackMetadataIterator iter(*this);
|
||||
|
@ -1162,7 +1162,6 @@ void FeedbackNexus::Print(std::ostream& os) { // NOLINT
|
||||
os << "ForIn:" << GetForInFeedback();
|
||||
break;
|
||||
}
|
||||
case FeedbackSlotKind::kCreateClosure:
|
||||
case FeedbackSlotKind::kLiteral:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
break;
|
||||
|
@ -161,12 +161,8 @@ Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
|
||||
isolate->factory()->no_feedback_cell();
|
||||
if (!feedback_vector.is_null()) {
|
||||
DCHECK(possibly_feedback_cell_slot->IsSmi());
|
||||
FeedbackSlot feedback_cells_slot(
|
||||
feedback_cell = feedback_vector->GetClosureFeedbackCell(
|
||||
Smi::ToInt(*possibly_feedback_cell_slot));
|
||||
feedback_cell = Handle<FeedbackCell>(
|
||||
FeedbackCell::cast(feedback_vector->Get(feedback_cells_slot)
|
||||
->GetHeapObjectAssumeStrong()),
|
||||
isolate);
|
||||
}
|
||||
// Copy the function and update its context. Use it as value.
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
|
@ -714,7 +714,7 @@ bytecodes: [
|
||||
/* 113 S> */ B(PopContext), R(3),
|
||||
B(Jump), U8(10),
|
||||
/* 126 S> */ B(LdaCurrentContextSlot), U8(4),
|
||||
B(Inc), U8(1),
|
||||
B(Inc), U8(0),
|
||||
/* 127 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
B(PopContext), R(3),
|
||||
B(JumpLoop), U8(41), I8(0),
|
||||
|
@ -24,7 +24,7 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 34 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
/* 36 E> */ B(StaLookupSlot), U8(2), U8(0),
|
||||
/* 52 S> */ B(LdaLookupGlobalSlot), U8(3), U8(1), U8(1),
|
||||
/* 52 S> */ B(LdaLookupGlobalSlot), U8(3), U8(0), U8(1),
|
||||
B(Star), R(2),
|
||||
B(LdaConstant), U8(4),
|
||||
B(Star), R(3),
|
||||
@ -39,10 +39,10 @@ bytecodes: [
|
||||
B(Mov), R(closure), R(6),
|
||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
|
||||
B(Star), R(2),
|
||||
/* 52 E> */ B(CallUndefinedReceiver1), R(2), R(3), U8(3),
|
||||
/* 62 S> */ B(LdaLookupGlobalSlot), U8(2), U8(5), U8(1),
|
||||
/* 52 E> */ B(CallUndefinedReceiver1), R(2), R(3), U8(2),
|
||||
/* 62 S> */ B(LdaLookupGlobalSlot), U8(2), U8(4), U8(1),
|
||||
B(Star), R(2),
|
||||
/* 69 E> */ B(CallUndefinedReceiver0), R(2), U8(7),
|
||||
/* 69 E> */ B(CallUndefinedReceiver0), R(2), U8(6),
|
||||
/* 73 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -120,11 +120,11 @@ bytecodes: [
|
||||
/* 106 S> */ B(LdaImmutableContextSlot), R(3), U8(5), U8(0),
|
||||
B(ToName), R(10),
|
||||
B(LdaConstant), U8(7),
|
||||
B(TestEqualStrict), R(10), U8(2),
|
||||
B(TestEqualStrict), R(10), U8(0),
|
||||
B(Mov), R(4), R(6),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
|
||||
B(CreateClosure), U8(8), U8(3), U8(2),
|
||||
B(CreateClosure), U8(8), U8(2), U8(2),
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(7),
|
||||
B(Star), R(5),
|
||||
@ -178,7 +178,7 @@ bytecodes: [
|
||||
B(PopContext), R(3),
|
||||
B(Mov), R(1), R(0),
|
||||
/* 87 S> */ B(Ldar), R(0),
|
||||
/* 94 E> */ B(Construct), R(0), R(0), U8(0), U8(1),
|
||||
/* 94 E> */ B(Construct), R(0), R(0), U8(0), U8(0),
|
||||
/* 102 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -111,7 +111,7 @@ bytecodes: [
|
||||
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
/* 45 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
/* 75 S> */ B(LdaCurrentContextSlot), U8(4),
|
||||
B(BitwiseOrSmi), I8(24), U8(1),
|
||||
B(BitwiseOrSmi), I8(24), U8(0),
|
||||
/* 77 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
B(LdaUndefined),
|
||||
/* 84 S> */ B(Return),
|
||||
|
@ -87,7 +87,7 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 41 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
B(Star), R(1),
|
||||
/* 64 E> */ B(CallUndefinedReceiver0), R(1), U8(1),
|
||||
/* 64 E> */ B(CallUndefinedReceiver0), R(1), U8(0),
|
||||
/* 68 S> */ B(LdaCurrentContextSlot), U8(4),
|
||||
/* 77 S> */ B(Return),
|
||||
]
|
||||
|
@ -217,7 +217,7 @@ bytecodes: [
|
||||
/* 53 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
B(Star), R(0),
|
||||
/* 78 S> */ B(LdaCurrentContextSlot), U8(4),
|
||||
B(Inc), U8(1),
|
||||
B(Inc), U8(0),
|
||||
/* 87 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
/* 89 S> */ B(Return),
|
||||
]
|
||||
@ -244,9 +244,9 @@ bytecodes: [
|
||||
/* 53 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
B(Star), R(0),
|
||||
/* 78 S> */ B(LdaCurrentContextSlot), U8(4),
|
||||
B(ToNumeric), U8(1),
|
||||
B(ToNumeric), U8(0),
|
||||
B(Star), R(2),
|
||||
B(Dec), U8(1),
|
||||
B(Dec), U8(0),
|
||||
/* 86 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
B(Ldar), R(2),
|
||||
/* 89 S> */ B(Return),
|
||||
|
@ -105,7 +105,7 @@ bytecodes: [
|
||||
/* 0 E> */ B(StackCheck),
|
||||
/* 16 S> */ B(LdaGlobal), U8(1), U8(0),
|
||||
B(Star), R(1),
|
||||
/* 16 E> */ B(CallUndefinedReceiver0), R(1), U8(3),
|
||||
/* 16 E> */ B(CallUndefinedReceiver0), R(1), U8(2),
|
||||
B(Star), R(0),
|
||||
/* 21 S> */ B(Return),
|
||||
]
|
||||
|
@ -105,7 +105,7 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 56 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(41),
|
||||
/* 56 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
/* 64 S> */ B(CreateClosure), U8(2), U8(1), U8(2),
|
||||
/* 64 S> */ B(CreateClosure), U8(2), U8(0), U8(2),
|
||||
/* 93 S> */ B(LdaImmutableCurrentContextSlot), U8(4),
|
||||
B(Star), R(1),
|
||||
B(LdaSmi), I8(1),
|
||||
|
@ -294,9 +294,9 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
/* 29 S> */ B(Ldar), R(0),
|
||||
/* 29 E> */ B(StaCurrentContextSlot), U8(4),
|
||||
/* 41 S> */ B(CreateClosure), U8(5), U8(12), U8(2),
|
||||
/* 41 S> */ B(CreateClosure), U8(5), U8(0), U8(2),
|
||||
B(Star), R(12),
|
||||
/* 67 E> */ B(CallUndefinedReceiver0), R(12), U8(13),
|
||||
/* 67 E> */ B(CallUndefinedReceiver0), R(12), U8(12),
|
||||
B(PopContext), R(11),
|
||||
B(Mov), R(0), R(10),
|
||||
B(JumpLoop), U8(60), I8(0),
|
||||
@ -312,7 +312,7 @@ bytecodes: [
|
||||
B(Star), R(9),
|
||||
B(Ldar), R(6),
|
||||
B(JumpIfToBooleanTrue), U8(60),
|
||||
B(LdaNamedProperty), R(3), U8(6), U8(15),
|
||||
B(LdaNamedProperty), R(3), U8(6), U8(14),
|
||||
B(Star), R(12),
|
||||
B(JumpIfUndefined), U8(52),
|
||||
B(JumpIfNull), U8(50),
|
||||
@ -325,7 +325,7 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kNewTypeError), R(13), U8(2),
|
||||
B(Throw),
|
||||
B(Mov), R(context), R(13),
|
||||
B(CallProperty0), R(12), R(3), U8(17),
|
||||
B(CallProperty0), R(12), R(3), U8(16),
|
||||
B(JumpIfJSReceiver), U8(21),
|
||||
B(Star), R(14),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(14), U8(1),
|
||||
|
@ -34,7 +34,7 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 34 S> */ B(CreateClosure), U8(0), U8(0), U8(2),
|
||||
B(Star), R(0),
|
||||
/* 56 E> */ B(CallUndefinedReceiver0), R(0), U8(1),
|
||||
/* 56 E> */ B(CallUndefinedReceiver0), R(0), U8(0),
|
||||
/* 58 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
@ -56,7 +56,7 @@ bytecodes: [
|
||||
B(Star), R(0),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(1),
|
||||
/* 67 E> */ B(CallUndefinedReceiver1), R(0), R(1), U8(1),
|
||||
/* 67 E> */ B(CallUndefinedReceiver1), R(0), R(1), U8(0),
|
||||
/* 70 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -29,10 +29,10 @@ bytecodes: [
|
||||
B(Mov), R(5), R(1),
|
||||
B(PopContext), R(2),
|
||||
B(Mov), R(1), R(0),
|
||||
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(1), U8(37),
|
||||
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(0),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(1), U8(2),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(1), U8(1),
|
||||
B(LdaUndefined),
|
||||
/* 110 S> */ B(Return),
|
||||
]
|
||||
@ -71,10 +71,10 @@ bytecodes: [
|
||||
B(Mov), R(1), R(0),
|
||||
/* 89 S> */ B(LdaZero),
|
||||
B(Star), R(3),
|
||||
B(CreateArrayLiteral), U8(3), U8(1), U8(37),
|
||||
B(CreateArrayLiteral), U8(3), U8(0), U8(37),
|
||||
B(Star), R(4),
|
||||
B(Ldar), R(0),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(2), U8(2),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(2), U8(1),
|
||||
B(LdaUndefined),
|
||||
/* 113 S> */ B(Return),
|
||||
]
|
||||
@ -111,35 +111,35 @@ bytecodes: [
|
||||
B(Mov), R(5), R(1),
|
||||
B(PopContext), R(2),
|
||||
B(Mov), R(1), R(0),
|
||||
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(1), U8(37),
|
||||
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
|
||||
B(Star), R(4),
|
||||
B(LdaConstant), U8(4),
|
||||
B(Star), R(3),
|
||||
/* 101 S> */ B(CreateArrayLiteral), U8(5), U8(2), U8(37),
|
||||
/* 101 S> */ B(CreateArrayLiteral), U8(5), U8(1), U8(37),
|
||||
B(Star), R(7),
|
||||
B(LdaNamedProperty), R(7), U8(6), U8(3),
|
||||
B(LdaNamedProperty), R(7), U8(6), U8(2),
|
||||
B(Star), R(8),
|
||||
B(CallProperty0), R(8), R(7), U8(5),
|
||||
B(CallProperty0), R(8), R(7), U8(4),
|
||||
B(Mov), R(5), R(2),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(6),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(7),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(6),
|
||||
B(Star), R(5),
|
||||
B(CallProperty0), R(5), R(6), U8(16),
|
||||
B(CallProperty0), R(5), R(6), U8(15),
|
||||
B(Star), R(9),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
|
||||
B(LdaNamedProperty), R(9), U8(8), U8(18),
|
||||
B(LdaNamedProperty), R(9), U8(8), U8(17),
|
||||
B(JumpIfToBooleanTrue), U8(19),
|
||||
B(LdaNamedProperty), R(9), U8(9), U8(9),
|
||||
B(StaInArrayLiteral), R(4), R(3), U8(14),
|
||||
B(LdaNamedProperty), R(9), U8(9), U8(8),
|
||||
B(StaInArrayLiteral), R(4), R(3), U8(13),
|
||||
B(Ldar), R(3),
|
||||
B(Inc), U8(13),
|
||||
B(Inc), U8(12),
|
||||
B(Star), R(3),
|
||||
B(JumpLoop), U8(33), I8(0),
|
||||
B(LdaSmi), I8(4),
|
||||
B(StaInArrayLiteral), R(4), R(3), U8(14),
|
||||
B(StaInArrayLiteral), R(4), R(3), U8(13),
|
||||
B(Mov), R(4), R(3),
|
||||
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
|
||||
B(LdaUndefined),
|
||||
|
@ -102,8 +102,8 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
|
||||
B(Star), R(0),
|
||||
/* 49 E> */ B(CreateClosure), U8(1), U8(1), U8(2),
|
||||
B(StaNamedOwnProperty), R(0), U8(2), U8(2),
|
||||
/* 49 E> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
B(StaNamedOwnProperty), R(0), U8(2), U8(1),
|
||||
B(Ldar), R(0),
|
||||
/* 66 S> */ B(Return),
|
||||
]
|
||||
@ -126,8 +126,8 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
|
||||
B(Star), R(0),
|
||||
/* 43 E> */ B(CreateClosure), U8(1), U8(1), U8(2),
|
||||
B(StaNamedOwnProperty), R(0), U8(2), U8(2),
|
||||
/* 43 E> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
B(StaNamedOwnProperty), R(0), U8(2), U8(1),
|
||||
B(Ldar), R(0),
|
||||
/* 67 S> */ B(Return),
|
||||
]
|
||||
@ -152,7 +152,7 @@ bytecodes: [
|
||||
B(Star), R(0),
|
||||
B(LdaConstant), U8(1),
|
||||
B(Star), R(2),
|
||||
B(CreateClosure), U8(2), U8(1), U8(2),
|
||||
B(CreateClosure), U8(2), U8(0), U8(2),
|
||||
B(Star), R(3),
|
||||
B(LdaNull),
|
||||
B(Star), R(4),
|
||||
@ -184,9 +184,9 @@ bytecodes: [
|
||||
B(Star), R(0),
|
||||
B(LdaConstant), U8(1),
|
||||
B(Star), R(2),
|
||||
B(CreateClosure), U8(2), U8(1), U8(2),
|
||||
B(CreateClosure), U8(2), U8(0), U8(2),
|
||||
B(Star), R(3),
|
||||
B(CreateClosure), U8(3), U8(2), U8(2),
|
||||
B(CreateClosure), U8(3), U8(1), U8(2),
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(5),
|
||||
@ -219,7 +219,7 @@ bytecodes: [
|
||||
B(Star), R(2),
|
||||
B(LdaNull),
|
||||
B(Star), R(3),
|
||||
B(CreateClosure), U8(2), U8(1), U8(2),
|
||||
B(CreateClosure), U8(2), U8(0), U8(2),
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(5),
|
||||
@ -388,7 +388,7 @@ bytecodes: [
|
||||
/* 64 E> */ B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(1),
|
||||
B(LdaConstant), U8(3),
|
||||
B(Star), R(3),
|
||||
/* 71 E> */ B(CreateClosure), U8(4), U8(3), U8(2),
|
||||
/* 71 E> */ B(CreateClosure), U8(4), U8(0), U8(2),
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(5),
|
||||
@ -396,7 +396,7 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), R(2), U8(4),
|
||||
B(LdaConstant), U8(3),
|
||||
B(Star), R(3),
|
||||
/* 84 E> */ B(CreateClosure), U8(5), U8(4), U8(2),
|
||||
/* 84 E> */ B(CreateClosure), U8(5), U8(1), U8(2),
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(5),
|
||||
|
@ -50,7 +50,7 @@ bytecodes: [
|
||||
B(Mov), R(7), R(3),
|
||||
B(CreateClosure), U8(4), U8(1), U8(2),
|
||||
B(Star), R(7),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(2),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(0),
|
||||
B(PopContext), R(4),
|
||||
B(Mov), R(3), R(0),
|
||||
/* 38 E> */ B(CreateBlockContext), U8(6),
|
||||
@ -59,7 +59,7 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
B(LdaTheHole),
|
||||
B(Star), R(8),
|
||||
B(CreateClosure), U8(8), U8(4), U8(2),
|
||||
B(CreateClosure), U8(8), U8(2), U8(2),
|
||||
B(Star), R(5),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(6),
|
||||
@ -73,15 +73,15 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(7), R(2),
|
||||
B(CreateClosure), U8(9), U8(5), U8(2),
|
||||
B(CreateClosure), U8(9), U8(3), U8(2),
|
||||
B(Star), R(7),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(6),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(2),
|
||||
B(PopContext), R(4),
|
||||
B(Mov), R(2), R(1),
|
||||
/* 136 S> */ B(Ldar), R(3),
|
||||
/* 136 E> */ B(Construct), R(3), R(0), U8(0), U8(8),
|
||||
/* 136 E> */ B(Construct), R(3), R(0), U8(0), U8(4),
|
||||
/* 145 S> */ B(Ldar), R(2),
|
||||
/* 145 E> */ B(Construct), R(2), R(0), U8(0), U8(10),
|
||||
/* 145 E> */ B(Construct), R(2), R(0), U8(0), U8(6),
|
||||
B(LdaUndefined),
|
||||
/* 154 S> */ B(Return),
|
||||
]
|
||||
@ -170,7 +170,7 @@ bytecodes: [
|
||||
B(Mov), R(9), R(5),
|
||||
B(CreateClosure), U8(6), U8(2), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(3),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(0),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(5), R(0),
|
||||
/* 38 E> */ B(CreateBlockContext), U8(8),
|
||||
@ -181,14 +181,14 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(5),
|
||||
B(LdaTheHole),
|
||||
B(Star), R(14),
|
||||
B(CreateClosure), U8(11), U8(5), U8(2),
|
||||
B(CreateClosure), U8(11), U8(3), U8(2),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(12),
|
||||
B(Mov), R(11), R(13),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
|
||||
B(Star), R(12),
|
||||
B(CreateClosure), U8(12), U8(6), U8(2),
|
||||
B(CreateClosure), U8(12), U8(4), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaConstant), U8(9),
|
||||
B(Star), R(8),
|
||||
@ -204,25 +204,25 @@ bytecodes: [
|
||||
B(Star), R(11),
|
||||
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
|
||||
B(StaCurrentContextSlot), U8(5),
|
||||
B(CreateClosure), U8(14), U8(7), U8(2),
|
||||
B(CreateClosure), U8(14), U8(5), U8(2),
|
||||
B(Star), R(11),
|
||||
B(CreateClosure), U8(15), U8(8), U8(2),
|
||||
B(CreateClosure), U8(15), U8(6), U8(2),
|
||||
B(Star), R(12),
|
||||
B(Mov), R(7), R(9),
|
||||
B(Mov), R(13), R(10),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(9), R(4),
|
||||
B(CreateClosure), U8(16), U8(9), U8(2),
|
||||
B(CreateClosure), U8(16), U8(7), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(10),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(2),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(4), R(1),
|
||||
/* 140 E> */ B(CreateBlockContext), U8(17),
|
||||
B(PushContext), R(6),
|
||||
B(LdaTheHole),
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
/* 356 E> */ B(CreateClosure), U8(19), U8(12), U8(2),
|
||||
/* 356 E> */ B(CreateClosure), U8(19), U8(8), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaConstant), U8(18),
|
||||
B(Star), R(8),
|
||||
@ -237,17 +237,17 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(9), R(3),
|
||||
B(CreateClosure), U8(20), U8(13), U8(2),
|
||||
B(CreateClosure), U8(20), U8(9), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(14),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(4),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(3), R(2),
|
||||
/* 430 S> */ B(Ldar), R(5),
|
||||
/* 430 E> */ B(Construct), R(5), R(0), U8(0), U8(16),
|
||||
/* 430 E> */ B(Construct), R(5), R(0), U8(0), U8(6),
|
||||
/* 439 S> */ B(Ldar), R(4),
|
||||
/* 439 E> */ B(Construct), R(4), R(0), U8(0), U8(18),
|
||||
/* 439 E> */ B(Construct), R(4), R(0), U8(0), U8(8),
|
||||
/* 448 S> */ B(Ldar), R(3),
|
||||
/* 448 E> */ B(Construct), R(3), R(0), U8(0), U8(20),
|
||||
/* 448 E> */ B(Construct), R(3), R(0), U8(0), U8(10),
|
||||
B(LdaUndefined),
|
||||
/* 458 S> */ B(Return),
|
||||
]
|
||||
|
@ -46,7 +46,7 @@ bytecodes: [
|
||||
B(Mov), R(7), R(3),
|
||||
B(CreateClosure), U8(4), U8(1), U8(2),
|
||||
B(Star), R(7),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(2),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(0),
|
||||
B(PopContext), R(4),
|
||||
B(Mov), R(3), R(0),
|
||||
/* 38 E> */ B(CreateBlockContext), U8(6),
|
||||
@ -55,7 +55,7 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
B(LdaTheHole),
|
||||
B(Star), R(8),
|
||||
B(CreateClosure), U8(8), U8(4), U8(2),
|
||||
B(CreateClosure), U8(8), U8(2), U8(2),
|
||||
B(Star), R(5),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(6),
|
||||
@ -66,15 +66,15 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(7), R(2),
|
||||
B(CreateClosure), U8(9), U8(5), U8(2),
|
||||
B(CreateClosure), U8(9), U8(3), U8(2),
|
||||
B(Star), R(7),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(6),
|
||||
B(StaNamedProperty), R(5), U8(5), U8(2),
|
||||
B(PopContext), R(4),
|
||||
B(Mov), R(2), R(1),
|
||||
/* 120 S> */ B(Ldar), R(3),
|
||||
/* 120 E> */ B(Construct), R(3), R(0), U8(0), U8(8),
|
||||
/* 120 E> */ B(Construct), R(3), R(0), U8(0), U8(4),
|
||||
/* 129 S> */ B(Ldar), R(2),
|
||||
/* 129 E> */ B(Construct), R(2), R(0), U8(0), U8(10),
|
||||
/* 129 E> */ B(Construct), R(2), R(0), U8(0), U8(6),
|
||||
B(LdaUndefined),
|
||||
/* 138 S> */ B(Return),
|
||||
]
|
||||
@ -155,7 +155,7 @@ bytecodes: [
|
||||
B(Mov), R(9), R(5),
|
||||
B(CreateClosure), U8(6), U8(2), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(3),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(0),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(5), R(0),
|
||||
/* 38 E> */ B(CreateBlockContext), U8(8),
|
||||
@ -164,37 +164,37 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
B(LdaTheHole),
|
||||
B(Star), R(14),
|
||||
B(CreateClosure), U8(11), U8(5), U8(2),
|
||||
B(CreateClosure), U8(11), U8(3), U8(2),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(12),
|
||||
B(Mov), R(11), R(13),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
|
||||
B(Star), R(12),
|
||||
B(CreateClosure), U8(12), U8(6), U8(2),
|
||||
B(CreateClosure), U8(12), U8(4), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaConstant), U8(9),
|
||||
B(Star), R(8),
|
||||
/* 133 S> */ B(LdaConstant), U8(5),
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
B(Star), R(11),
|
||||
B(CreateClosure), U8(13), U8(7), U8(2),
|
||||
B(CreateClosure), U8(13), U8(5), U8(2),
|
||||
B(Star), R(12),
|
||||
B(Mov), R(7), R(9),
|
||||
B(Mov), R(13), R(10),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(9), R(4),
|
||||
B(CreateClosure), U8(14), U8(8), U8(2),
|
||||
B(CreateClosure), U8(14), U8(6), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(2),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(4), R(1),
|
||||
/* 90 E> */ B(CreateBlockContext), U8(15),
|
||||
B(PushContext), R(6),
|
||||
B(LdaTheHole),
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
/* 236 E> */ B(CreateClosure), U8(17), U8(11), U8(2),
|
||||
/* 236 E> */ B(CreateClosure), U8(17), U8(7), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaConstant), U8(16),
|
||||
B(Star), R(8),
|
||||
@ -206,17 +206,17 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(9), R(3),
|
||||
B(CreateClosure), U8(18), U8(12), U8(2),
|
||||
B(CreateClosure), U8(18), U8(8), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(13),
|
||||
B(StaNamedProperty), R(7), U8(7), U8(4),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(3), R(2),
|
||||
/* 329 S> */ B(Ldar), R(5),
|
||||
/* 329 E> */ B(Construct), R(5), R(0), U8(0), U8(15),
|
||||
/* 329 E> */ B(Construct), R(5), R(0), U8(0), U8(6),
|
||||
/* 338 S> */ B(Ldar), R(4),
|
||||
/* 338 E> */ B(Construct), R(4), R(0), U8(0), U8(17),
|
||||
/* 338 E> */ B(Construct), R(4), R(0), U8(0), U8(8),
|
||||
/* 347 S> */ B(Ldar), R(3),
|
||||
/* 347 E> */ B(Construct), R(3), R(0), U8(0), U8(19),
|
||||
/* 347 E> */ B(Construct), R(3), R(0), U8(0), U8(10),
|
||||
B(LdaUndefined),
|
||||
/* 356 S> */ B(Return),
|
||||
]
|
||||
|
@ -186,16 +186,16 @@ bytecodes: [
|
||||
B(TestEqual), R(2), U8(3),
|
||||
B(JumpIfFalse), U8(22),
|
||||
/* 17 E> */ B(StackCheck),
|
||||
/* 48 S> */ B(CreateClosure), U8(1), U8(4), U8(2),
|
||||
/* 48 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
|
||||
B(Star), R(5),
|
||||
/* 74 E> */ B(CallUndefinedReceiver0), R(5), U8(5),
|
||||
/* 74 E> */ B(CallUndefinedReceiver0), R(5), U8(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(2),
|
||||
B(LdaCurrentContextSlot), U8(4),
|
||||
B(Star), R(0),
|
||||
B(JumpLoop), U8(24), I8(1),
|
||||
B(LdaSmi), I8(1),
|
||||
/* 78 E> */ B(TestEqual), R(2), U8(7),
|
||||
/* 78 E> */ B(TestEqual), R(2), U8(6),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(PopContext), R(4),
|
||||
B(Jump), U8(7),
|
||||
|
@ -50,7 +50,7 @@ bytecodes: [
|
||||
/* 92 S> */ B(LdaConstant), U8(4),
|
||||
B(Star), R(10),
|
||||
B(LdaConstant), U8(5),
|
||||
B(TestEqualStrict), R(10), U8(1),
|
||||
B(TestEqualStrict), R(10), U8(0),
|
||||
B(Mov), R(5), R(7),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
|
||||
@ -59,12 +59,12 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(5), R(3),
|
||||
B(CreateClosure), U8(6), U8(2), U8(2),
|
||||
B(CreateClosure), U8(6), U8(1), U8(2),
|
||||
B(Star), R(7),
|
||||
B(StaNamedProperty), R(5), U8(7), U8(3),
|
||||
B(CreateClosure), U8(8), U8(5), U8(2),
|
||||
B(StaNamedProperty), R(5), U8(7), U8(1),
|
||||
B(CreateClosure), U8(8), U8(2), U8(2),
|
||||
B(Star), R(9),
|
||||
B(CallProperty0), R(9), R(3), U8(6),
|
||||
B(CallProperty0), R(9), R(3), U8(3),
|
||||
B(PopContext), R(4),
|
||||
B(Mov), R(3), R(0),
|
||||
/* 38 E> */ B(CreateBlockContext), U8(9),
|
||||
@ -75,7 +75,7 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(5),
|
||||
B(LdaTheHole),
|
||||
B(Star), R(8),
|
||||
B(CreateClosure), U8(11), U8(8), U8(2),
|
||||
B(CreateClosure), U8(11), U8(3), U8(2),
|
||||
B(Star), R(5),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(6),
|
||||
@ -85,7 +85,7 @@ bytecodes: [
|
||||
/* 176 S> */ B(LdaConstant), U8(4),
|
||||
B(Star), R(10),
|
||||
B(LdaConstant), U8(5),
|
||||
B(TestEqualStrict), R(10), U8(1),
|
||||
B(TestEqualStrict), R(10), U8(0),
|
||||
B(Mov), R(5), R(7),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
|
||||
@ -94,18 +94,18 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(5), R(2),
|
||||
B(CreateClosure), U8(12), U8(9), U8(2),
|
||||
B(CreateClosure), U8(12), U8(4), U8(2),
|
||||
B(Star), R(7),
|
||||
B(StaNamedProperty), R(5), U8(7), U8(10),
|
||||
B(CreateClosure), U8(13), U8(12), U8(2),
|
||||
B(StaNamedProperty), R(5), U8(7), U8(5),
|
||||
B(CreateClosure), U8(13), U8(5), U8(2),
|
||||
B(Star), R(9),
|
||||
B(CallProperty0), R(9), R(2), U8(13),
|
||||
B(CallProperty0), R(9), R(2), U8(7),
|
||||
B(PopContext), R(4),
|
||||
B(Mov), R(2), R(1),
|
||||
/* 197 S> */ B(Ldar), R(0),
|
||||
/* 197 E> */ B(Construct), R(0), R(0), U8(0), U8(15),
|
||||
/* 197 E> */ B(Construct), R(0), R(0), U8(0), U8(9),
|
||||
/* 206 S> */ B(Ldar), R(2),
|
||||
/* 206 E> */ B(Construct), R(2), R(0), U8(0), U8(17),
|
||||
/* 206 E> */ B(Construct), R(2), R(0), U8(0), U8(11),
|
||||
B(LdaUndefined),
|
||||
/* 215 S> */ B(Return),
|
||||
]
|
||||
@ -194,7 +194,7 @@ bytecodes: [
|
||||
/* 109 S> */ B(LdaConstant), U8(6),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(7),
|
||||
B(TestEqualStrict), R(12), U8(2),
|
||||
B(TestEqualStrict), R(12), U8(0),
|
||||
B(Mov), R(13), R(10),
|
||||
B(Mov), R(7), R(9),
|
||||
B(JumpIfFalse), U8(7),
|
||||
@ -204,12 +204,12 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(7), R(5),
|
||||
B(CreateClosure), U8(8), U8(3), U8(2),
|
||||
B(CreateClosure), U8(8), U8(2), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(9), U8(4),
|
||||
B(CreateClosure), U8(10), U8(6), U8(2),
|
||||
B(StaNamedProperty), R(7), U8(9), U8(1),
|
||||
B(CreateClosure), U8(10), U8(3), U8(2),
|
||||
B(Star), R(11),
|
||||
B(CallProperty0), R(11), R(5), U8(7),
|
||||
B(CallProperty0), R(11), R(5), U8(3),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(5), R(0),
|
||||
/* 38 E> */ B(CreateBlockContext), U8(11),
|
||||
@ -220,14 +220,14 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(5),
|
||||
B(LdaTheHole),
|
||||
B(Star), R(14),
|
||||
B(CreateClosure), U8(14), U8(9), U8(2),
|
||||
B(CreateClosure), U8(14), U8(4), U8(2),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(13),
|
||||
B(Star), R(12),
|
||||
B(Mov), R(11), R(13),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
|
||||
B(Star), R(12),
|
||||
B(CreateClosure), U8(15), U8(10), U8(2),
|
||||
B(CreateClosure), U8(15), U8(5), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaConstant), U8(12),
|
||||
B(Star), R(8),
|
||||
@ -237,24 +237,24 @@ bytecodes: [
|
||||
/* 210 S> */ B(LdaConstant), U8(6),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(7),
|
||||
B(TestEqualStrict), R(12), U8(2),
|
||||
B(TestEqualStrict), R(12), U8(0),
|
||||
B(Mov), R(7), R(9),
|
||||
B(Mov), R(13), R(10),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
|
||||
B(Ldar), R(12),
|
||||
B(StaCurrentContextSlot), U8(5),
|
||||
B(CreateClosure), U8(16), U8(11), U8(2),
|
||||
B(CreateClosure), U8(16), U8(6), U8(2),
|
||||
B(Star), R(13),
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(6),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(7), R(4),
|
||||
B(CreateClosure), U8(17), U8(12), U8(2),
|
||||
B(CreateClosure), U8(17), U8(7), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(9), U8(13),
|
||||
B(CreateClosure), U8(18), U8(15), U8(2),
|
||||
B(StaNamedProperty), R(7), U8(9), U8(5),
|
||||
B(CreateClosure), U8(18), U8(8), U8(2),
|
||||
B(Star), R(11),
|
||||
B(CallProperty0), R(11), R(4), U8(16),
|
||||
B(CallProperty0), R(11), R(4), U8(7),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(4), R(1),
|
||||
/* 122 E> */ B(CreateBlockContext), U8(19),
|
||||
@ -263,7 +263,7 @@ bytecodes: [
|
||||
B(StaCurrentContextSlot), U8(4),
|
||||
B(LdaTheHole),
|
||||
B(StaCurrentContextSlot), U8(5),
|
||||
/* 313 E> */ B(CreateClosure), U8(21), U8(18), U8(2),
|
||||
/* 313 E> */ B(CreateClosure), U8(21), U8(9), U8(2),
|
||||
B(Star), R(7),
|
||||
B(LdaConstant), U8(20),
|
||||
B(Star), R(8),
|
||||
@ -273,7 +273,7 @@ bytecodes: [
|
||||
/* 378 S> */ B(LdaConstant), U8(6),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(7),
|
||||
B(TestEqualStrict), R(12), U8(2),
|
||||
B(TestEqualStrict), R(12), U8(0),
|
||||
B(Mov), R(4), R(10),
|
||||
B(Mov), R(7), R(9),
|
||||
B(JumpIfFalse), U8(7),
|
||||
@ -283,22 +283,22 @@ bytecodes: [
|
||||
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(7), R(3),
|
||||
B(CreateClosure), U8(22), U8(19), U8(2),
|
||||
B(CreateClosure), U8(22), U8(10), U8(2),
|
||||
B(Star), R(9),
|
||||
B(StaNamedProperty), R(7), U8(9), U8(20),
|
||||
B(CreateClosure), U8(23), U8(22), U8(2),
|
||||
B(StaNamedProperty), R(7), U8(9), U8(9),
|
||||
B(CreateClosure), U8(23), U8(11), U8(2),
|
||||
B(Star), R(11),
|
||||
B(Ldar), R(3),
|
||||
B(StaNamedProperty), R(11), U8(24), U8(23),
|
||||
B(CallProperty0), R(11), R(3), U8(25),
|
||||
B(StaNamedProperty), R(11), U8(24), U8(11),
|
||||
B(CallProperty0), R(11), R(3), U8(13),
|
||||
B(PopContext), R(6),
|
||||
B(Mov), R(3), R(2),
|
||||
/* 456 S> */ B(Ldar), R(0),
|
||||
/* 456 E> */ B(Construct), R(0), R(0), U8(0), U8(27),
|
||||
/* 456 E> */ B(Construct), R(0), R(0), U8(0), U8(15),
|
||||
/* 465 S> */ B(Ldar), R(1),
|
||||
/* 465 E> */ B(Construct), R(1), R(0), U8(0), U8(29),
|
||||
/* 465 E> */ B(Construct), R(1), R(0), U8(0), U8(17),
|
||||
/* 474 S> */ B(Ldar), R(3),
|
||||
/* 474 E> */ B(Construct), R(3), R(0), U8(0), U8(31),
|
||||
/* 474 E> */ B(Construct), R(3), R(0), U8(0), U8(19),
|
||||
B(LdaUndefined),
|
||||
/* 483 S> */ B(Return),
|
||||
]
|
||||
|
@ -181,14 +181,14 @@ bytecodes: [
|
||||
B(Star), R(1),
|
||||
/* 80 S> */ B(LdaConstant), U8(1),
|
||||
B(Star), R(3),
|
||||
/* 98 E> */ B(CallUndefinedReceiver2), R(2), R(0), R(1), U8(1),
|
||||
/* 96 E> */ B(Add), R(3), U8(3),
|
||||
/* 98 E> */ B(CallUndefinedReceiver2), R(2), R(0), R(1), U8(0),
|
||||
/* 96 E> */ B(Add), R(3), U8(2),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(0),
|
||||
/* 108 E> */ B(Add), R(3), U8(4),
|
||||
/* 108 E> */ B(Add), R(3), U8(3),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(1),
|
||||
/* 112 E> */ B(Add), R(3), U8(5),
|
||||
/* 112 E> */ B(Add), R(3), U8(4),
|
||||
/* 116 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -200,17 +200,17 @@ bytecodes: [
|
||||
B(Star), R(1),
|
||||
/* 80 S> */ B(LdaConstant), U8(1),
|
||||
B(Star), R(3),
|
||||
/* 96 E> */ B(CallUndefinedReceiver2), R(2), R(0), R(1), U8(2),
|
||||
/* 96 E> */ B(CallUndefinedReceiver2), R(2), R(0), R(1), U8(1),
|
||||
B(ToString),
|
||||
B(Add), R(3), U8(1),
|
||||
B(Add), R(3), U8(0),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(0),
|
||||
/* 108 E> */ B(ToString),
|
||||
B(Add), R(3), U8(1),
|
||||
B(Add), R(3), U8(0),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(1),
|
||||
/* 112 E> */ B(ToString),
|
||||
B(Add), R(3), U8(1),
|
||||
B(Add), R(3), U8(0),
|
||||
/* 116 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -23,10 +23,10 @@ bytecodes: [
|
||||
/* 0 E> */ B(StackCheck),
|
||||
/* 8 S> */ B(CreateObjectLiteral), U8(1), U8(2), U8(41),
|
||||
B(Star), R(1),
|
||||
/* 16 E> */ B(CreateClosure), U8(2), U8(3), U8(0),
|
||||
B(StaNamedOwnProperty), R(1), U8(3), U8(4),
|
||||
/* 16 E> */ B(CreateClosure), U8(2), U8(0), U8(0),
|
||||
B(StaNamedOwnProperty), R(1), U8(3), U8(3),
|
||||
B(Ldar), R(1),
|
||||
/* 8 E> */ B(StaGlobal), U8(4), U8(6),
|
||||
/* 8 E> */ B(StaGlobal), U8(4), U8(5),
|
||||
B(LdaUndefined),
|
||||
/* 34 S> */ B(Return),
|
||||
]
|
||||
|
@ -89,15 +89,11 @@ TEST(VectorStructure) {
|
||||
{
|
||||
FeedbackVectorSpec spec(&zone);
|
||||
spec.AddForInSlot();
|
||||
spec.AddCreateClosureSlot();
|
||||
spec.AddFeedbackCellForCreateClosure();
|
||||
spec.AddForInSlot();
|
||||
vector = NewFeedbackVector(isolate, &spec);
|
||||
FeedbackVectorHelper helper(vector);
|
||||
CHECK_EQ(1,
|
||||
FeedbackMetadata::GetSlotSize(FeedbackSlotKind::kCreateClosure));
|
||||
FeedbackSlot slot = helper.slot(1);
|
||||
FeedbackCell cell =
|
||||
FeedbackCell::cast(vector->Get(slot)->GetHeapObjectAssumeStrong());
|
||||
FeedbackCell cell = *vector->GetClosureFeedbackCell(0);
|
||||
CHECK_EQ(cell->value(), *factory->undefined_value());
|
||||
}
|
||||
}
|
||||
|
@ -542,10 +542,12 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadFeedbackVector) {
|
||||
Matcher<Node*> load_vector_cell_matcher = m.IsLoad(
|
||||
MachineType::AnyTagged(), load_function_matcher,
|
||||
c::IsIntPtrConstant(JSFunction::kFeedbackCellOffset - kHeapObjectTag));
|
||||
EXPECT_THAT(
|
||||
feedback_vector,
|
||||
Matcher<Node*> load_feedback_vector_matcher =
|
||||
m.IsLoad(MachineType::AnyTagged(), load_vector_cell_matcher,
|
||||
c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag)));
|
||||
c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag));
|
||||
Matcher<Node*> merge_node =
|
||||
i::compiler::IsPhi(_, _, load_feedback_vector_matcher, _);
|
||||
EXPECT_THAT(feedback_vector, merge_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user