[ic] Introduce new IC for storing into array literals.
... and use it in the implementation of array literal spreads, replacing calls to %AppendElement. Array spreads in destructuring will be taken care of in a separate CL. Bug: v8:5940, v8:7446 Change-Id: Idec52398902a7fd3c1244852cf73246f142404f0 Reviewed-on: https://chromium-review.googlesource.com/915364 Commit-Queue: Georg Neis <neis@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#51709}
This commit is contained in:
parent
824358f07b
commit
2e2860f74f
@ -214,6 +214,7 @@ namespace internal {
|
||||
TFH(LoadIC_Uninitialized, LoadWithVector) \
|
||||
TFH(StoreGlobalIC_Slow, StoreWithVector) \
|
||||
TFH(StoreIC_Uninitialized, StoreWithVector) \
|
||||
TFH(StoreInArrayLiteralIC_Slow, StoreWithVector) \
|
||||
\
|
||||
/* Microtask helpers */ \
|
||||
TFS(EnqueueMicrotask, kMicrotask) \
|
||||
@ -598,6 +599,7 @@ namespace internal {
|
||||
TFH(StoreICTrampoline, Store) \
|
||||
TFH(KeyedStoreIC, StoreWithVector) \
|
||||
TFH(KeyedStoreICTrampoline, Store) \
|
||||
TFH(StoreInArrayLiteralIC, StoreWithVector) \
|
||||
TFH(LoadGlobalIC, LoadGlobalWithVector) \
|
||||
TFH(LoadGlobalICInsideTypeof, LoadGlobalWithVector) \
|
||||
TFH(LoadGlobalICTrampoline, LoadGlobal) \
|
||||
|
@ -55,6 +55,15 @@ TF_BUILTIN(KeyedStoreIC_Slow, CodeStubAssembler) {
|
||||
receiver, name);
|
||||
}
|
||||
|
||||
TF_BUILTIN(StoreInArrayLiteralIC_Slow, CodeStubAssembler) {
|
||||
Node* array = Parameter(Descriptor::kReceiver);
|
||||
Node* index = Parameter(Descriptor::kName);
|
||||
Node* value = Parameter(Descriptor::kValue);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, context, value, array,
|
||||
index);
|
||||
}
|
||||
|
||||
TF_BUILTIN(LoadGlobalIC_Slow, CodeStubAssembler) {
|
||||
Node* name = Parameter(Descriptor::kName);
|
||||
Node* slot = Parameter(Descriptor::kSlot);
|
||||
|
@ -35,6 +35,7 @@ IC_BUILTIN(StoreIC)
|
||||
IC_BUILTIN(StoreICTrampoline)
|
||||
IC_BUILTIN(KeyedStoreIC)
|
||||
IC_BUILTIN(KeyedStoreICTrampoline)
|
||||
IC_BUILTIN(StoreInArrayLiteralIC)
|
||||
|
||||
IC_BUILTIN_PARAM(LoadGlobalIC, LoadGlobalIC, NOT_INSIDE_TYPEOF)
|
||||
IC_BUILTIN_PARAM(LoadGlobalICInsideTypeof, LoadGlobalIC, INSIDE_TYPEOF)
|
||||
|
@ -506,6 +506,15 @@ TF_STUB(StoreSlowElementStub, CodeStubAssembler) {
|
||||
receiver, name);
|
||||
}
|
||||
|
||||
TF_STUB(StoreInArrayLiteralSlowStub, CodeStubAssembler) {
|
||||
Node* array = Parameter(Descriptor::kReceiver);
|
||||
Node* index = Parameter(Descriptor::kName);
|
||||
Node* value = Parameter(Descriptor::kValue);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, context, value, array,
|
||||
index);
|
||||
}
|
||||
|
||||
TF_STUB(StoreFastElementStub, CodeStubAssembler) {
|
||||
Comment("StoreFastElementStub: js_array=%d, elements_kind=%s, store_mode=%d",
|
||||
stub->is_js_array(), ElementsKindToString(stub->elements_kind()),
|
||||
|
@ -37,8 +37,9 @@ class Node;
|
||||
V(JSEntry) \
|
||||
V(MathPow) \
|
||||
V(ProfileEntryHook) \
|
||||
V(StoreSlowElement) \
|
||||
/* --- TurboFanCodeStubs --- */ \
|
||||
V(StoreSlowElement) \
|
||||
V(StoreInArrayLiteralSlow) \
|
||||
V(ArrayNoArgumentConstructor) \
|
||||
V(ArraySingleArgumentConstructor) \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
@ -929,6 +930,18 @@ class StoreSlowElementStub : public TurboFanCodeStub {
|
||||
DEFINE_TURBOFAN_CODE_STUB(StoreSlowElement, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class StoreInArrayLiteralSlowStub : public TurboFanCodeStub {
|
||||
public:
|
||||
StoreInArrayLiteralSlowStub(Isolate* isolate, KeyedAccessStoreMode mode)
|
||||
: TurboFanCodeStub(isolate) {
|
||||
minor_key_ = CommonStoreModeBits::encode(mode);
|
||||
}
|
||||
|
||||
private:
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
|
||||
DEFINE_TURBOFAN_CODE_STUB(StoreInArrayLiteralSlow, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ElementsTransitionAndStoreStub : public TurboFanCodeStub {
|
||||
public:
|
||||
ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind,
|
||||
|
@ -1007,6 +1007,32 @@ void BytecodeGraphBuilder::VisitStaGlobal() {
|
||||
environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaInArrayLiteral() {
|
||||
PrepareEagerCheckpoint();
|
||||
Node* value = environment()->LookupAccumulator();
|
||||
Node* array =
|
||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
||||
Node* index =
|
||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
|
||||
VectorSlotPair feedback =
|
||||
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
|
||||
const Operator* op = javascript()->StoreInArrayLiteral(feedback);
|
||||
|
||||
JSTypeHintLowering::LoweringResult lowering =
|
||||
TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot());
|
||||
if (lowering.IsExit()) return;
|
||||
|
||||
Node* node = nullptr;
|
||||
if (lowering.IsSideEffectFree()) {
|
||||
node = lowering.value();
|
||||
} else {
|
||||
DCHECK(!lowering.Changed());
|
||||
node = NewNode(op, array, index, value);
|
||||
}
|
||||
|
||||
environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
|
||||
PrepareEagerCheckpoint();
|
||||
|
||||
|
@ -279,6 +279,16 @@ void JSGenericLowering::LowerJSStoreDataPropertyInLiteral(Node* node) {
|
||||
ReplaceWithRuntimeCall(node, Runtime::kDefineDataPropertyInLiteral);
|
||||
}
|
||||
|
||||
void JSGenericLowering::LowerJSStoreInArrayLiteral(Node* node) {
|
||||
Callable callable =
|
||||
Builtins::CallableFor(isolate(), Builtins::kStoreInArrayLiteralIC);
|
||||
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
|
||||
FeedbackParameter const& p = FeedbackParameterOf(node->op());
|
||||
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
|
||||
node->InsertInput(zone(), 4, jsgraph()->HeapConstant(p.feedback().vector()));
|
||||
ReplaceWithStubCall(node, callable, flags);
|
||||
}
|
||||
|
||||
void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
|
||||
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
|
||||
Callable callable =
|
||||
|
@ -98,6 +98,8 @@ Reduction JSNativeContextSpecialization::Reduce(Node* node) {
|
||||
return ReduceJSStoreNamedOwn(node);
|
||||
case IrOpcode::kJSStoreDataPropertyInLiteral:
|
||||
return ReduceJSStoreDataPropertyInLiteral(node);
|
||||
case IrOpcode::kJSStoreInArrayLiteral:
|
||||
return ReduceJSStoreInArrayLiteral(node);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1126,7 +1128,8 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
|
||||
AccessMode access_mode, KeyedAccessLoadMode load_mode,
|
||||
KeyedAccessStoreMode store_mode) {
|
||||
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
|
||||
node->opcode() == IrOpcode::kJSStoreProperty);
|
||||
node->opcode() == IrOpcode::kJSStoreProperty ||
|
||||
node->opcode() == IrOpcode::kJSStoreInArrayLiteral);
|
||||
Node* receiver = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
@ -2091,6 +2094,45 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
|
||||
return Replace(value);
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceJSStoreInArrayLiteral(
|
||||
Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSStoreInArrayLiteral, node->opcode());
|
||||
FeedbackParameter const& p = FeedbackParameterOf(node->op());
|
||||
Node* const receiver = NodeProperties::GetValueInput(node, 0);
|
||||
Node* const index = NodeProperties::GetValueInput(node, 1);
|
||||
Node* const value = NodeProperties::GetValueInput(node, 2);
|
||||
Node* const effect = NodeProperties::GetEffectInput(node);
|
||||
|
||||
// Extract receiver maps from the keyed store IC using the FeedbackNexus.
|
||||
if (!p.feedback().IsValid()) return NoChange();
|
||||
FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot());
|
||||
|
||||
// Extract the keyed access store mode from the keyed store IC.
|
||||
KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode();
|
||||
|
||||
// Extract receiver maps from the {nexus}.
|
||||
MapHandles receiver_maps;
|
||||
if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
|
||||
return NoChange();
|
||||
} else if (receiver_maps.empty()) {
|
||||
if (flags() & kBailoutOnUninitialized) {
|
||||
return ReduceSoftDeoptimize(
|
||||
node,
|
||||
DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
|
||||
}
|
||||
return NoChange();
|
||||
}
|
||||
DCHECK(!nexus.IsUninitialized());
|
||||
DCHECK_EQ(ELEMENT, nexus.GetKeyType());
|
||||
|
||||
if (nexus.ic_state() == MEGAMORPHIC) return NoChange();
|
||||
|
||||
// Try to lower the element access based on the {receiver_maps}.
|
||||
return ReduceElementAccess(node, index, value, receiver_maps,
|
||||
AccessMode::kStoreInLiteral, STANDARD_LOAD,
|
||||
store_mode);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
|
||||
@ -2113,7 +2155,6 @@ JSNativeContextSpecialization::BuildElementAccess(
|
||||
Node* receiver, Node* index, Node* value, Node* effect, Node* control,
|
||||
ElementAccessInfo const& access_info, AccessMode access_mode,
|
||||
KeyedAccessLoadMode load_mode, KeyedAccessStoreMode store_mode) {
|
||||
DCHECK_NE(AccessMode::kStoreInLiteral, access_mode);
|
||||
|
||||
// TODO(bmeurer): We currently specialize based on elements kind. We should
|
||||
// also be able to properly support strings and other JSObjects here.
|
||||
@ -2346,7 +2387,8 @@ JSNativeContextSpecialization::BuildElementAccess(
|
||||
// Check if we might need to grow the {elements} backing store.
|
||||
if (IsGrowStoreMode(store_mode)) {
|
||||
// For growing stores we validate the {index} below.
|
||||
DCHECK_EQ(AccessMode::kStore, access_mode);
|
||||
DCHECK(access_mode == AccessMode::kStore ||
|
||||
access_mode == AccessMode::kStoreInLiteral);
|
||||
} else if (load_mode == LOAD_IGNORE_OUT_OF_BOUNDS &&
|
||||
CanTreatHoleAsUndefined(receiver_maps)) {
|
||||
// Check that the {index} is a valid array index, we do the actual
|
||||
@ -2478,7 +2520,8 @@ JSNativeContextSpecialization::BuildElementAccess(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DCHECK_EQ(AccessMode::kStore, access_mode);
|
||||
DCHECK(access_mode == AccessMode::kStore ||
|
||||
access_mode == AccessMode::kStoreInLiteral);
|
||||
if (IsSmiElementsKind(elements_kind)) {
|
||||
value = effect = graph()->NewNode(
|
||||
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
|
||||
|
@ -73,6 +73,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
|
||||
Reduction ReduceJSStoreProperty(Node* node);
|
||||
Reduction ReduceJSStoreNamedOwn(Node* node);
|
||||
Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);
|
||||
Reduction ReduceJSStoreInArrayLiteral(Node* node);
|
||||
|
||||
Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
|
||||
MapHandles const& receiver_maps,
|
||||
|
@ -258,7 +258,8 @@ std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) {
|
||||
FeedbackParameter const& FeedbackParameterOf(const Operator* op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray ||
|
||||
op->opcode() == IrOpcode::kJSInstanceOf ||
|
||||
op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral);
|
||||
op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral ||
|
||||
op->opcode() == IrOpcode::kJSStoreInArrayLiteral);
|
||||
return OpParameter<FeedbackParameter>(op);
|
||||
}
|
||||
|
||||
@ -745,6 +746,17 @@ const Operator* JSOperatorBuilder::StoreDataPropertyInLiteral(
|
||||
parameters); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::StoreInArrayLiteral(
|
||||
const VectorSlotPair& feedback) {
|
||||
FeedbackParameter parameters(feedback);
|
||||
return new (zone()) Operator1<FeedbackParameter>( // --
|
||||
IrOpcode::kJSStoreInArrayLiteral,
|
||||
Operator::kNoThrow, // opcode
|
||||
"JSStoreInArrayLiteral", // name
|
||||
3, 1, 1, 0, 1, 0, // counts
|
||||
parameters); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::CallForwardVarargs(size_t arity,
|
||||
uint32_t start_index) {
|
||||
CallForwardVarargsParameters parameters(arity, start_index);
|
||||
|
@ -714,6 +714,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
|
||||
const Operator* StoreNamedOwn(Handle<Name> name,
|
||||
VectorSlotPair const& feedback);
|
||||
const Operator* StoreDataPropertyInLiteral(const VectorSlotPair& feedback);
|
||||
const Operator* StoreInArrayLiteral(const VectorSlotPair& feedback);
|
||||
|
||||
const Operator* DeleteProperty();
|
||||
|
||||
|
@ -477,7 +477,8 @@ JSTypeHintLowering::ReduceStoreKeyedOperation(const Operator* op, Node* obj,
|
||||
Node* key, Node* val,
|
||||
Node* effect, Node* control,
|
||||
FeedbackSlot slot) const {
|
||||
DCHECK_EQ(IrOpcode::kJSStoreProperty, op->opcode());
|
||||
DCHECK(op->opcode() == IrOpcode::kJSStoreProperty ||
|
||||
op->opcode() == IrOpcode::kJSStoreInArrayLiteral);
|
||||
DCHECK(!slot.IsInvalid());
|
||||
FeedbackNexus nexus(feedback_vector(), slot);
|
||||
if (Node* node = TryBuildSoftDeopt(
|
||||
|
@ -159,6 +159,7 @@
|
||||
V(JSStoreNamedOwn) \
|
||||
V(JSStoreGlobal) \
|
||||
V(JSStoreDataPropertyInLiteral) \
|
||||
V(JSStoreInArrayLiteral) \
|
||||
V(JSDeleteProperty) \
|
||||
V(JSHasProperty) \
|
||||
V(JSGetSuperConstructor)
|
||||
|
@ -1374,6 +1374,8 @@ Type* Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) { UNREACHABLE(); }
|
||||
|
||||
Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
|
||||
return Type::Boolean();
|
||||
}
|
||||
|
@ -739,8 +739,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
|
||||
CHECK(StoreNamedOwnParametersOf(node->op()).feedback().IsValid());
|
||||
break;
|
||||
case IrOpcode::kJSStoreDataPropertyInLiteral:
|
||||
case IrOpcode::kJSStoreInArrayLiteral:
|
||||
// Type is empty.
|
||||
CheckNotTyped(node);
|
||||
CHECK(FeedbackParameterOf(node->op()).feedback().IsValid());
|
||||
break;
|
||||
case IrOpcode::kJSDeleteProperty:
|
||||
case IrOpcode::kJSHasProperty:
|
||||
|
@ -933,6 +933,7 @@ class RuntimeCallTimer final {
|
||||
V(KeyedStoreIC_SlowStub) \
|
||||
V(KeyedStoreIC_StoreFastElementStub) \
|
||||
V(KeyedStoreIC_StoreElementStub) \
|
||||
V(StoreInArrayLiteralIC_SlowStub) \
|
||||
V(LoadGlobalIC_LoadScriptContextField) \
|
||||
V(LoadGlobalIC_SlowStub) \
|
||||
V(LoadIC_FunctionPrototypeStub) \
|
||||
|
@ -64,6 +64,7 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
case FeedbackSlotKind::kStoreGlobalStrict:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
return 2;
|
||||
|
||||
@ -247,6 +248,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
|
||||
case FeedbackSlotKind::kStoreGlobalStrict:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kTypeProfile: {
|
||||
if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
|
||||
|
@ -163,6 +163,8 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
|
||||
return "StoreKeyedSloppy";
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
return "StoreKeyedStrict";
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral:
|
||||
return "StoreInArrayLiteral";
|
||||
case FeedbackSlotKind::kBinaryOp:
|
||||
return "BinaryOp";
|
||||
case FeedbackSlotKind::kCompareOp:
|
||||
@ -268,6 +270,7 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
case FeedbackSlotKind::kStoreOwnNamed:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kTypeProfile:
|
||||
case FeedbackSlotKind::kInstanceOf:
|
||||
@ -469,6 +472,7 @@ bool FeedbackNexus::Clear() {
|
||||
case FeedbackSlotKind::kStoreNamedStrict:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral:
|
||||
case FeedbackSlotKind::kStoreOwnNamed:
|
||||
case FeedbackSlotKind::kLoadProperty:
|
||||
case FeedbackSlotKind::kLoadKeyed:
|
||||
@ -548,10 +552,12 @@ InlineCacheState FeedbackNexus::StateFromFeedback() const {
|
||||
}
|
||||
return UNINITIALIZED;
|
||||
}
|
||||
|
||||
case FeedbackSlotKind::kStoreNamedSloppy:
|
||||
case FeedbackSlotKind::kStoreNamedStrict:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral:
|
||||
case FeedbackSlotKind::kStoreOwnNamed:
|
||||
case FeedbackSlotKind::kLoadProperty:
|
||||
case FeedbackSlotKind::kLoadKeyed: {
|
||||
@ -773,7 +779,8 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
|
||||
int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
|
||||
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
|
||||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
|
||||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()));
|
||||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
|
||||
IsStoreInArrayLiteralICKind(kind()));
|
||||
|
||||
Isolate* isolate = GetIsolate();
|
||||
Object* feedback = GetFeedback();
|
||||
@ -851,7 +858,8 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
|
||||
bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const {
|
||||
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
|
||||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
|
||||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()));
|
||||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
|
||||
IsStoreInArrayLiteralICKind(kind()));
|
||||
|
||||
Object* feedback = GetFeedback();
|
||||
Isolate* isolate = GetIsolate();
|
||||
@ -914,7 +922,7 @@ KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
|
||||
}
|
||||
|
||||
KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
|
||||
DCHECK(IsKeyedStoreICKind(kind()));
|
||||
DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()));
|
||||
KeyedAccessStoreMode mode = STANDARD_STORE;
|
||||
MapHandles maps;
|
||||
ObjectHandles handlers;
|
||||
@ -956,7 +964,8 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
|
||||
}
|
||||
|
||||
IcCheckType FeedbackNexus::GetKeyType() const {
|
||||
DCHECK(IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()));
|
||||
DCHECK(IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) ||
|
||||
IsStoreInArrayLiteralICKind(kind()));
|
||||
Object* feedback = GetFeedback();
|
||||
if (feedback == *FeedbackVector::MegamorphicSentinel(GetIsolate())) {
|
||||
return static_cast<IcCheckType>(Smi::ToInt(GetFeedbackExtra()));
|
||||
|
@ -42,6 +42,7 @@ enum class FeedbackSlotKind {
|
||||
kStoreNamedStrict,
|
||||
kStoreOwnNamed,
|
||||
kStoreKeyedStrict,
|
||||
kStoreInArrayLiteral,
|
||||
kBinaryOp,
|
||||
kCompareOp,
|
||||
kStoreDataPropertyInLiteral,
|
||||
@ -94,6 +95,10 @@ inline bool IsKeyedStoreICKind(FeedbackSlotKind kind) {
|
||||
kind == FeedbackSlotKind::kStoreKeyedStrict;
|
||||
}
|
||||
|
||||
inline bool IsStoreInArrayLiteralICKind(FeedbackSlotKind kind) {
|
||||
return kind == FeedbackSlotKind::kStoreInArrayLiteral;
|
||||
}
|
||||
|
||||
inline bool IsGlobalICKind(FeedbackSlotKind kind) {
|
||||
return IsLoadGlobalICKind(kind) || IsStoreGlobalICKind(kind);
|
||||
}
|
||||
@ -364,6 +369,10 @@ class V8_EXPORT_PRIVATE FeedbackVectorSpec {
|
||||
: FeedbackSlotKind::kStoreKeyedSloppy);
|
||||
}
|
||||
|
||||
FeedbackSlot AddStoreInArrayLiteralICSlot() {
|
||||
return AddSlot(FeedbackSlotKind::kStoreInArrayLiteral);
|
||||
}
|
||||
|
||||
FeedbackSlot AddBinaryOpICSlot() {
|
||||
return AddSlot(FeedbackSlotKind::kBinaryOp);
|
||||
}
|
||||
|
@ -2840,6 +2840,86 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {
|
||||
}
|
||||
}
|
||||
|
||||
void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
|
||||
Label miss(this, Label::kDeferred);
|
||||
{
|
||||
VARIABLE(var_handler, MachineRepresentation::kTagged);
|
||||
|
||||
Label if_handler(this, &var_handler),
|
||||
try_polymorphic(this, Label::kDeferred),
|
||||
try_megamorphic(this, Label::kDeferred);
|
||||
|
||||
Node* array_map = LoadReceiverMap(p->receiver);
|
||||
GotoIf(IsDeprecatedMap(array_map), &miss);
|
||||
Node* feedback =
|
||||
TryMonomorphicCase(p->slot, p->vector, array_map, &if_handler,
|
||||
&var_handler, &try_polymorphic);
|
||||
|
||||
BIND(&if_handler);
|
||||
{
|
||||
Comment("StoreInArrayLiteralIC_if_handler");
|
||||
// This is a stripped-down version of HandleStoreICHandlerCase.
|
||||
|
||||
Node* handler = var_handler.value();
|
||||
Label if_transitioning_element_store(this);
|
||||
GotoIfNot(IsCode(handler), &if_transitioning_element_store);
|
||||
StoreWithVectorDescriptor descriptor(isolate());
|
||||
TailCallStub(descriptor, handler, p->context, p->receiver, p->name,
|
||||
p->value, p->slot, p->vector);
|
||||
|
||||
BIND(&if_transitioning_element_store);
|
||||
{
|
||||
Node* transition_map_cell = LoadHandlerDataField(handler, 1);
|
||||
Node* transition_map = LoadWeakCellValue(transition_map_cell, &miss);
|
||||
CSA_ASSERT(this, IsMap(transition_map));
|
||||
GotoIf(IsDeprecatedMap(transition_map), &miss);
|
||||
Node* code = LoadObjectField(handler, StoreHandler::kSmiHandlerOffset);
|
||||
CSA_ASSERT(this, IsCode(code));
|
||||
StoreTransitionDescriptor descriptor(isolate());
|
||||
TailCallStub(descriptor, code, p->context, p->receiver, p->name,
|
||||
transition_map, p->value, p->slot, p->vector);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&try_polymorphic);
|
||||
{
|
||||
Comment("StoreInArrayLiteralIC_try_polymorphic");
|
||||
GotoIfNot(
|
||||
WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
|
||||
&try_megamorphic);
|
||||
HandlePolymorphicCase(array_map, feedback, &if_handler, &var_handler,
|
||||
&miss, 2);
|
||||
}
|
||||
|
||||
BIND(&try_megamorphic);
|
||||
{
|
||||
Comment("StoreInArrayLiteralIC_try_megamorphic");
|
||||
CSA_ASSERT(
|
||||
this,
|
||||
Word32Or(
|
||||
Word32Or(
|
||||
IsWeakCellMap(LoadMap(feedback)),
|
||||
WordEqual(feedback,
|
||||
LoadRoot(Heap::kuninitialized_symbolRootIndex))),
|
||||
WordEqual(feedback,
|
||||
LoadRoot(Heap::kmegamorphic_symbolRootIndex))));
|
||||
GotoIfNot(
|
||||
WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
|
||||
&miss);
|
||||
TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, p->context,
|
||||
p->value, p->receiver, p->name);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&miss);
|
||||
{
|
||||
Comment("StoreInArrayLiteralIC_miss");
|
||||
// TODO(neis): Introduce Runtime::kStoreInArrayLiteralIC_Miss.
|
||||
TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot,
|
||||
p->vector, p->receiver, p->name);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////// Public methods.
|
||||
|
||||
void AccessorAssembler::GenerateLoadIC() {
|
||||
@ -3096,5 +3176,19 @@ void AccessorAssembler::GenerateKeyedStoreICTrampoline() {
|
||||
TailCallStub(callable, context, receiver, name, value, slot, vector);
|
||||
}
|
||||
|
||||
void AccessorAssembler::GenerateStoreInArrayLiteralIC() {
|
||||
typedef StoreWithVectorDescriptor Descriptor;
|
||||
|
||||
Node* array = Parameter(Descriptor::kReceiver);
|
||||
Node* index = Parameter(Descriptor::kName);
|
||||
Node* value = Parameter(Descriptor::kValue);
|
||||
Node* slot = Parameter(Descriptor::kSlot);
|
||||
Node* vector = Parameter(Descriptor::kVector);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
StoreICParameters p(context, array, index, value, slot, vector);
|
||||
StoreInArrayLiteralIC(&p);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -43,6 +43,8 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
void GenerateKeyedStoreIC();
|
||||
void GenerateKeyedStoreICTrampoline();
|
||||
|
||||
void GenerateStoreInArrayLiteralIC();
|
||||
|
||||
void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name,
|
||||
Label* if_handler, Variable* var_handler,
|
||||
Label* if_miss);
|
||||
@ -127,6 +129,7 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
void StoreGlobalIC_PropertyCellCase(Node* property_cell, Node* value,
|
||||
ExitPoint* exit_point, Label* miss);
|
||||
void KeyedStoreIC(const StoreICParameters* p);
|
||||
void StoreInArrayLiteralIC(const StoreICParameters* p);
|
||||
|
||||
// IC dispatcher behavior.
|
||||
|
||||
|
123
src/ic/ic.cc
123
src/ic/ic.cc
@ -95,14 +95,16 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
||||
if (IsKeyedLoadIC()) {
|
||||
KeyedAccessLoadMode mode = nexus()->GetKeyedAccessLoadMode();
|
||||
modifier = GetModifier(mode);
|
||||
} else if (IsKeyedStoreIC()) {
|
||||
} else if (IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind())) {
|
||||
KeyedAccessStoreMode mode = nexus()->GetKeyedAccessStoreMode();
|
||||
modifier = GetModifier(mode);
|
||||
}
|
||||
|
||||
bool keyed_prefix = is_keyed() && !IsStoreInArrayLiteralICKind(kind());
|
||||
|
||||
if (!(FLAG_ic_stats &
|
||||
v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING)) {
|
||||
LOG(isolate(), ICEvent(type, is_keyed(), map, *name,
|
||||
LOG(isolate(), ICEvent(type, keyed_prefix, map, *name,
|
||||
TransitionMarkFromState(old_state),
|
||||
TransitionMarkFromState(new_state), modifier,
|
||||
slow_stub_reason_));
|
||||
@ -111,7 +113,7 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
|
||||
|
||||
ICStats::instance()->Begin();
|
||||
ICInfo& ic_info = ICStats::instance()->Current();
|
||||
ic_info.type = is_keyed() ? "Keyed" : "";
|
||||
ic_info.type = keyed_prefix ? "Keyed" : "";
|
||||
ic_info.type += type;
|
||||
|
||||
Object* maybe_function =
|
||||
@ -1690,6 +1692,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
|
||||
|
||||
for (Handle<Map> map : target_receiver_maps) {
|
||||
if (!map.is_null() && map->instance_type() == JS_VALUE_TYPE) {
|
||||
DCHECK(!IsStoreInArrayLiteralICKind(kind()));
|
||||
set_slow_stub_reason("JSValue");
|
||||
return;
|
||||
}
|
||||
@ -1776,11 +1779,13 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
|
||||
size_t external_arrays = 0;
|
||||
for (Handle<Map> map : target_receiver_maps) {
|
||||
if (map->has_fixed_typed_array_elements()) {
|
||||
DCHECK(!IsStoreInArrayLiteralICKind(kind()));
|
||||
external_arrays++;
|
||||
}
|
||||
}
|
||||
if (external_arrays != 0 &&
|
||||
external_arrays != target_receiver_maps.size()) {
|
||||
DCHECK(!IsStoreInArrayLiteralICKind(kind()));
|
||||
set_slow_stub_reason(
|
||||
"unsupported combination of external and normal arrays");
|
||||
return;
|
||||
@ -1834,7 +1839,8 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
|
||||
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
|
||||
store_mode == STORE_NO_TRANSITION_HANDLE_COW);
|
||||
DCHECK(!receiver_map->DictionaryElementsInPrototypeChainOnly());
|
||||
DCHECK_IMPLIES(receiver_map->DictionaryElementsInPrototypeChainOnly(),
|
||||
IsStoreInArrayLiteralICKind(kind()));
|
||||
|
||||
if (receiver_map->IsJSProxyMap()) {
|
||||
return StoreHandler::StoreProxy(isolate());
|
||||
@ -1854,11 +1860,17 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
StoreFastElementStub(isolate(), is_jsarray, elements_kind, store_mode)
|
||||
.GetCode();
|
||||
if (receiver_map->has_fixed_typed_array_elements()) return stub;
|
||||
} else if (IsStoreInArrayLiteralICKind(kind())) {
|
||||
TRACE_HANDLER_STATS(isolate(), StoreInArrayLiteralIC_SlowStub);
|
||||
stub = StoreInArrayLiteralSlowStub(isolate(), store_mode).GetCode();
|
||||
} else {
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
|
||||
DCHECK_EQ(DICTIONARY_ELEMENTS, elements_kind);
|
||||
stub = StoreSlowElementStub(isolate(), store_mode).GetCode();
|
||||
}
|
||||
|
||||
if (IsStoreInArrayLiteralICKind(kind())) return stub;
|
||||
|
||||
Handle<Object> validity_cell =
|
||||
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
|
||||
if (validity_cell.is_null()) return stub;
|
||||
@ -1892,7 +1904,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers(
|
||||
// TODO(mvstanton): Consider embedding store_mode in the state of the slow
|
||||
// keyed store ic for uniformity.
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
|
||||
handler = BUILTIN_CODE(isolate(), KeyedStoreIC_Slow);
|
||||
handler = slow_stub();
|
||||
|
||||
} else {
|
||||
{
|
||||
@ -2092,7 +2104,56 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
|
||||
return store_handle;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void StoreOwnElement(Handle<JSArray> array, Handle<Object> index,
|
||||
Handle<Object> value) {
|
||||
DCHECK(index->IsNumber());
|
||||
bool success = false;
|
||||
LookupIterator it = LookupIterator::PropertyOrElement(
|
||||
array->GetIsolate(), array, index, &success, LookupIterator::OWN);
|
||||
DCHECK(success);
|
||||
|
||||
CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE,
|
||||
kThrowOnError)
|
||||
.FromJust());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void StoreInArrayLiteralIC::Store(Handle<JSArray> array, Handle<Object> index,
|
||||
Handle<Object> value) {
|
||||
DCHECK(!array->map()->IsMapInArrayPrototypeChain());
|
||||
DCHECK(index->IsNumber());
|
||||
|
||||
if (!FLAG_use_ic || MigrateDeprecated(array)) {
|
||||
StoreOwnElement(array, index, value);
|
||||
TraceIC("StoreInArrayLiteralIC", index);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(neis): Convert HeapNumber to Smi if possible?
|
||||
|
||||
KeyedAccessStoreMode store_mode = STANDARD_STORE;
|
||||
if (index->IsSmi()) {
|
||||
DCHECK_GE(Smi::ToInt(*index), 0);
|
||||
uint32_t index32 = static_cast<uint32_t>(Smi::ToInt(*index));
|
||||
store_mode = GetStoreMode(array, index32, value);
|
||||
}
|
||||
|
||||
Handle<Map> old_array_map(array->map(), isolate());
|
||||
StoreOwnElement(array, index, value);
|
||||
|
||||
if (index->IsSmi()) {
|
||||
DCHECK(!old_array_map->is_abandoned_prototype_map());
|
||||
UpdateStoreElement(old_array_map, store_mode);
|
||||
} else {
|
||||
set_slow_stub_reason("index out of Smi range");
|
||||
}
|
||||
|
||||
if (vector_needs_update()) {
|
||||
ConfigureVectorState(MEGAMORPHIC, index);
|
||||
}
|
||||
TraceIC("StoreInArrayLiteralIC", index);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Static IC stub generators.
|
||||
@ -2312,11 +2373,24 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) {
|
||||
Handle<Object> receiver = args.at(3);
|
||||
Handle<Object> key = args.at(4);
|
||||
FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
|
||||
KeyedStoreIC ic(isolate, vector, vector_slot);
|
||||
ic.UpdateState(receiver, key);
|
||||
RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
|
||||
}
|
||||
FeedbackSlotKind kind = vector->GetKind(vector_slot);
|
||||
|
||||
// The elements store stubs miss into this function, but they are shared by
|
||||
// different ICs.
|
||||
if (IsKeyedStoreICKind(kind)) {
|
||||
KeyedStoreIC ic(isolate, vector, vector_slot);
|
||||
ic.UpdateState(receiver, key);
|
||||
RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
|
||||
} else {
|
||||
DCHECK(IsStoreInArrayLiteralICKind(kind));
|
||||
DCHECK(receiver->IsJSArray());
|
||||
DCHECK(key->IsNumber());
|
||||
StoreInArrayLiteralIC ic(isolate, vector, vector_slot);
|
||||
ic.UpdateState(receiver, key);
|
||||
ic.Store(Handle<JSArray>::cast(receiver), key, value);
|
||||
return *value;
|
||||
}
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
|
||||
HandleScope scope(isolate);
|
||||
@ -2328,12 +2402,24 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
|
||||
Handle<Object> object = args.at(3);
|
||||
Handle<Object> key = args.at(4);
|
||||
FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
|
||||
LanguageMode language_mode = vector->GetLanguageMode(vector_slot);
|
||||
FeedbackSlotKind kind = vector->GetKind(vector_slot);
|
||||
DCHECK(IsStoreICKind(kind) || IsKeyedStoreICKind(kind));
|
||||
LanguageMode language_mode = GetLanguageModeFromSlotKind(kind);
|
||||
RETURN_RESULT_OR_FAILURE(
|
||||
isolate,
|
||||
Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(3, args.length());
|
||||
// Runtime functions don't follow the IC's calling convention.
|
||||
Handle<Object> value = args.at(0);
|
||||
Handle<Object> array = args.at(1);
|
||||
Handle<Object> index = args.at(2);
|
||||
StoreOwnElement(Handle<JSArray>::cast(array), index, value);
|
||||
return *value;
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
|
||||
HandleScope scope(isolate);
|
||||
@ -2346,14 +2432,23 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
|
||||
Handle<Smi> slot = args.at<Smi>(4);
|
||||
Handle<FeedbackVector> vector = args.at<FeedbackVector>(5);
|
||||
FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
|
||||
LanguageMode language_mode = vector->GetLanguageMode(vector_slot);
|
||||
FeedbackSlotKind kind = vector->GetKind(vector_slot);
|
||||
|
||||
if (object->IsJSObject()) {
|
||||
JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
|
||||
map->elements_kind());
|
||||
}
|
||||
RETURN_RESULT_OR_FAILURE(
|
||||
isolate,
|
||||
Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
|
||||
|
||||
if (IsStoreInArrayLiteralICKind(kind)) {
|
||||
StoreOwnElement(Handle<JSArray>::cast(object), key, value);
|
||||
return *value;
|
||||
} else {
|
||||
DCHECK(IsKeyedStoreICKind(kind) || IsStoreICKind(kind));
|
||||
LanguageMode language_mode = GetLanguageModeFromSlotKind(kind);
|
||||
RETURN_RESULT_OR_FAILURE(
|
||||
isolate,
|
||||
Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
27
src/ic/ic.h
27
src/ic/ic.h
@ -58,7 +58,7 @@ class IC {
|
||||
}
|
||||
bool IsAnyStore() const {
|
||||
return IsStoreIC() || IsStoreOwnIC() || IsStoreGlobalIC() ||
|
||||
IsKeyedStoreIC();
|
||||
IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind());
|
||||
}
|
||||
|
||||
static inline bool IsHandler(Object* object);
|
||||
@ -131,7 +131,10 @@ class IC {
|
||||
bool IsStoreIC() const { return IsStoreICKind(kind_); }
|
||||
bool IsStoreOwnIC() const { return IsStoreOwnICKind(kind_); }
|
||||
bool IsKeyedStoreIC() const { return IsKeyedStoreICKind(kind_); }
|
||||
bool is_keyed() const { return IsKeyedLoadIC() || IsKeyedStoreIC(); }
|
||||
bool is_keyed() const {
|
||||
return IsKeyedLoadIC() || IsKeyedStoreIC() ||
|
||||
IsStoreInArrayLiteralICKind(kind_);
|
||||
}
|
||||
bool ShouldRecomputeHandler(Handle<String> name);
|
||||
|
||||
Handle<Map> receiver_map() { return receiver_map_; }
|
||||
@ -368,6 +371,10 @@ class KeyedStoreIC : public StoreIC {
|
||||
void UpdateStoreElement(Handle<Map> receiver_map,
|
||||
KeyedAccessStoreMode store_mode);
|
||||
|
||||
Handle<Code> slow_stub() const override {
|
||||
return BUILTIN_CODE(isolate(), KeyedStoreIC_Slow);
|
||||
}
|
||||
|
||||
private:
|
||||
Handle<Map> ComputeTransitionedMap(Handle<Map> map,
|
||||
KeyedAccessStoreMode store_mode);
|
||||
@ -382,6 +389,22 @@ class KeyedStoreIC : public StoreIC {
|
||||
friend class IC;
|
||||
};
|
||||
|
||||
class StoreInArrayLiteralIC : public KeyedStoreIC {
|
||||
public:
|
||||
StoreInArrayLiteralIC(Isolate* isolate, Handle<FeedbackVector> vector,
|
||||
FeedbackSlot slot)
|
||||
: KeyedStoreIC(isolate, vector, slot) {
|
||||
DCHECK(IsStoreInArrayLiteralICKind(kind()));
|
||||
}
|
||||
|
||||
void Store(Handle<JSArray> array, Handle<Object> index, Handle<Object> value);
|
||||
|
||||
private:
|
||||
Handle<Code> slow_stub() const override {
|
||||
return BUILTIN_CODE(isolate(), StoreInArrayLiteralIC_Slow);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -864,6 +864,12 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
|
||||
return *this;
|
||||
}
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreInArrayLiteral(
|
||||
Register array, Register index, int feedback_slot) {
|
||||
OutputStaInArrayLiteral(array, index, feedback_slot);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreHomeObjectProperty(
|
||||
Register object, int feedback_slot, LanguageMode language_mode) {
|
||||
size_t name_index = HomeObjectSymbolConstantPoolEntry();
|
||||
|
@ -160,6 +160,10 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
|
||||
BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
|
||||
int feedback_slot,
|
||||
LanguageMode language_mode);
|
||||
// Store an own element in an array literal. The value to be stored should be
|
||||
// in the accumulator.
|
||||
BytecodeArrayBuilder& StoreInArrayLiteral(Register array, Register index,
|
||||
int feedback_slot);
|
||||
// Store the home object property. The value to be stored should be in the
|
||||
// accumulator.
|
||||
BytecodeArrayBuilder& StoreHomeObjectProperty(Register object,
|
||||
|
@ -2300,17 +2300,18 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
builder()->CreateArrayLiteral(entry, literal_index, flags);
|
||||
array_literals_.push_back(std::make_pair(expr, entry));
|
||||
|
||||
Register index = register_allocator()->NewRegister();
|
||||
Register literal = register_allocator()->NewRegister();
|
||||
builder()->StoreAccumulatorInRegister(literal);
|
||||
|
||||
// We'll reuse the same literal slot for all of the non-constant
|
||||
// subexpressions that use a keyed store IC.
|
||||
|
||||
Register index = register_allocator()->NewRegister();
|
||||
int array_index = 0;
|
||||
|
||||
// Evaluate all the non-constant subexpressions and store them into the
|
||||
// newly cloned array.
|
||||
FeedbackSlot slot;
|
||||
int array_index = 0;
|
||||
ZoneList<Expression*>::iterator iter = expr->BeginValue();
|
||||
for (; iter != expr->FirstSpreadOrEndValue(); ++iter, array_index++) {
|
||||
Expression* subexpr = *iter;
|
||||
@ -2326,32 +2327,37 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
|
||||
language_mode());
|
||||
}
|
||||
if (iter != expr->EndValue()) {
|
||||
builder()->LoadLiteral(array_index).StoreAccumulatorInRegister(index);
|
||||
}
|
||||
|
||||
// Handle spread elements and elements following.
|
||||
// Handle the first spread element and everything that follows.
|
||||
FeedbackSlot element_slot = feedback_spec()->AddStoreInArrayLiteralICSlot();
|
||||
FeedbackSlot index_slot = feedback_spec()->AddBinaryOpICSlot();
|
||||
FeedbackSlot length_slot =
|
||||
feedback_spec()->AddStoreICSlot(LanguageMode::kStrict);
|
||||
for (; iter != expr->EndValue(); ++iter) {
|
||||
Expression* subexpr = *iter;
|
||||
if (subexpr->IsSpread()) {
|
||||
BuildArrayLiteralSpread(subexpr->AsSpread(), literal);
|
||||
BuildArrayLiteralSpread(subexpr->AsSpread(), literal, index, index_slot,
|
||||
element_slot);
|
||||
} else if (!subexpr->IsTheHoleLiteral()) {
|
||||
// Perform %AppendElement(array, <subexpr>)
|
||||
RegisterAllocationScope register_scope(this);
|
||||
RegisterList args = register_allocator()->NewRegisterList(2);
|
||||
builder()->MoveRegister(literal, args[0]);
|
||||
VisitForRegisterValue(subexpr, args[1]);
|
||||
builder()->CallRuntime(Runtime::kAppendElement, args);
|
||||
// literal[index++] = subexpr
|
||||
VisitForAccumulatorValue(subexpr);
|
||||
builder()
|
||||
->StoreInArrayLiteral(literal, index, feedback_index(element_slot))
|
||||
.LoadAccumulatorWithRegister(index)
|
||||
.UnaryOperation(Token::INC, feedback_index(index_slot))
|
||||
.StoreAccumulatorInRegister(index);
|
||||
} else {
|
||||
// Peform ++<array>.length;
|
||||
// TODO(caitp): Why can't we just %AppendElement(array, <The Hole>?)
|
||||
// literal.length = ++index
|
||||
auto length = ast_string_constants()->length_string();
|
||||
builder()->LoadNamedProperty(
|
||||
literal, length, feedback_index(feedback_spec()->AddLoadICSlot()));
|
||||
builder()->UnaryOperation(
|
||||
Token::INC, feedback_index(feedback_spec()->AddBinaryOpICSlot()));
|
||||
builder()->StoreNamedProperty(
|
||||
literal, length,
|
||||
feedback_index(
|
||||
feedback_spec()->AddStoreICSlot(LanguageMode::kStrict)),
|
||||
LanguageMode::kStrict);
|
||||
builder()
|
||||
->LoadAccumulatorWithRegister(index)
|
||||
.UnaryOperation(Token::INC, feedback_index(index_slot))
|
||||
.StoreAccumulatorInRegister(index)
|
||||
.StoreNamedProperty(literal, length, feedback_index(length_slot),
|
||||
LanguageMode::kStrict);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2359,34 +2365,41 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
builder()->LoadAccumulatorWithRegister(literal);
|
||||
}
|
||||
|
||||
void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread,
|
||||
Register array) {
|
||||
void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
|
||||
Register index,
|
||||
FeedbackSlot index_slot,
|
||||
FeedbackSlot element_slot) {
|
||||
RegisterAllocationScope register_scope(this);
|
||||
RegisterList args = register_allocator()->NewRegisterList(2);
|
||||
builder()->MoveRegister(array, args[0]);
|
||||
Register next_result = args[1];
|
||||
Register value = register_allocator()->NewRegister();
|
||||
|
||||
builder()->SetExpressionAsStatementPosition(spread->expression());
|
||||
IteratorRecord iterator =
|
||||
BuildGetIteratorRecord(spread->expression(), IteratorType::kNormal);
|
||||
|
||||
LoopBuilder loop_builder(builder(), nullptr, nullptr);
|
||||
loop_builder.LoopHeader();
|
||||
|
||||
// Call the iterator's .next() method. Break from the loop if the `done`
|
||||
// property is truthy, otherwise load the value from the iterator result and
|
||||
// append the argument.
|
||||
BuildIteratorNext(iterator, next_result);
|
||||
BuildIteratorNext(iterator, value);
|
||||
builder()->LoadNamedProperty(
|
||||
next_result, ast_string_constants()->done_string(),
|
||||
value, ast_string_constants()->done_string(),
|
||||
feedback_index(feedback_spec()->AddLoadICSlot()));
|
||||
loop_builder.BreakIfTrue(ToBooleanMode::kConvertToBoolean);
|
||||
|
||||
loop_builder.LoopBody();
|
||||
builder()
|
||||
->LoadNamedProperty(next_result, ast_string_constants()->value_string(),
|
||||
// value = value.value
|
||||
->LoadNamedProperty(value, ast_string_constants()->value_string(),
|
||||
feedback_index(feedback_spec()->AddLoadICSlot()))
|
||||
.StoreAccumulatorInRegister(args[1])
|
||||
.CallRuntime(Runtime::kAppendElement, args);
|
||||
.StoreAccumulatorInRegister(value)
|
||||
// array[index] = value
|
||||
.StoreInArrayLiteral(array, index, feedback_index(element_slot))
|
||||
// index++
|
||||
.LoadAccumulatorWithRegister(index)
|
||||
.UnaryOperation(Token::INC, feedback_index(index_slot))
|
||||
.StoreAccumulatorInRegister(index);
|
||||
loop_builder.BindContinueTarget();
|
||||
loop_builder.JumpToHeader(loop_depth_);
|
||||
}
|
||||
|
@ -173,7 +173,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
BytecodeLabel* if_called,
|
||||
BytecodeLabels* if_notcalled);
|
||||
|
||||
void BuildArrayLiteralSpread(Spread* spread, Register array);
|
||||
void BuildArrayLiteralSpread(Spread* spread, Register array, Register index,
|
||||
FeedbackSlot index_slot,
|
||||
FeedbackSlot element_slot);
|
||||
|
||||
void AllocateTopLevelRegisters();
|
||||
void VisitArgumentsObject(Variable* variable);
|
||||
|
@ -97,6 +97,8 @@ namespace interpreter {
|
||||
OperandType::kIdx, OperandType::kIdx) \
|
||||
V(StaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kIdx) \
|
||||
V(StaInArrayLiteral, AccumulatorUse::kReadWrite, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kIdx) \
|
||||
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \
|
||||
V(CollectTypeProfile, AccumulatorUse::kRead, OperandType::kImm) \
|
||||
|
@ -555,7 +555,9 @@ class InterpreterStoreNamedPropertyAssembler : public InterpreterAssembler {
|
||||
Node* context = GetContext();
|
||||
Node* result = CallStub(ic.descriptor(), code_target, context, object, name,
|
||||
value, smi_slot, feedback_vector);
|
||||
// It doesn't really matter what we write to the accumulator here, since we
|
||||
// To avoid special logic in the deoptimizer to re-materialize the value in
|
||||
// the accumulator, we overwrite the accumulator after the IC call. It
|
||||
// doesn't really matter what we write to the accumulator here, since we
|
||||
// restore to the correct value on the outside. Storing the result means we
|
||||
// don't need to keep unnecessary state alive across the callstub.
|
||||
SetAccumulator(result);
|
||||
@ -599,7 +601,35 @@ IGNITION_HANDLER(StaKeyedProperty, InterpreterAssembler) {
|
||||
Node* context = GetContext();
|
||||
Node* result = CallStub(ic.descriptor(), code_target, context, object, name,
|
||||
value, smi_slot, feedback_vector);
|
||||
// It doesn't really matter what we write to the accumulator here, since we
|
||||
// To avoid special logic in the deoptimizer to re-materialize the value in
|
||||
// the accumulator, we overwrite the accumulator after the IC call. It
|
||||
// doesn't really matter what we write to the accumulator here, since we
|
||||
// restore to the correct value on the outside. Storing the result means we
|
||||
// don't need to keep unnecessary state alive across the callstub.
|
||||
SetAccumulator(result);
|
||||
Dispatch();
|
||||
}
|
||||
|
||||
// StaInArrayLiteral <array> <index> <slot>
|
||||
//
|
||||
// Calls the StoreInArrayLiteralIC at FeedbackVector slot <slot> for <array> and
|
||||
// the key <index> with the value in the accumulator.
|
||||
IGNITION_HANDLER(StaInArrayLiteral, InterpreterAssembler) {
|
||||
Callable ic =
|
||||
Builtins::CallableFor(isolate(), Builtins::kStoreInArrayLiteralIC);
|
||||
Node* code_target = HeapConstant(ic.code());
|
||||
Node* array = LoadRegisterAtOperandIndex(0);
|
||||
Node* index = LoadRegisterAtOperandIndex(1);
|
||||
Node* value = GetAccumulator();
|
||||
Node* raw_slot = BytecodeOperandIdx(2);
|
||||
Node* smi_slot = SmiTag(raw_slot);
|
||||
Node* feedback_vector = LoadFeedbackVector();
|
||||
Node* context = GetContext();
|
||||
Node* result = CallStub(ic.descriptor(), code_target, context, array, index,
|
||||
value, smi_slot, feedback_vector);
|
||||
// To avoid special logic in the deoptimizer to re-materialize the value in
|
||||
// the accumulator, we overwrite the accumulator after the IC call. It
|
||||
// doesn't really matter what we write to the accumulator here, since we
|
||||
// restore to the correct value on the outside. Storing the result means we
|
||||
// don't need to keep unnecessary state alive across the callstub.
|
||||
SetAccumulator(result);
|
||||
|
@ -859,7 +859,8 @@ void FeedbackNexus::Print(std::ostream& os) { // NOLINT
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kInstanceOf:
|
||||
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict: {
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
case FeedbackSlotKind::kStoreInArrayLiteral: {
|
||||
os << ICState2String(StateFromFeedback());
|
||||
break;
|
||||
}
|
||||
|
@ -577,6 +577,8 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
|
||||
// A spread can only occur as the last component. It is not handled by
|
||||
// RecurseIntoSubpattern above.
|
||||
|
||||
// TODO(neis): Use IC instead of %AppendElement.
|
||||
|
||||
// let array = [];
|
||||
// while (!done) {
|
||||
// done = true; // If .next, .done or .value throws, don't close.
|
||||
|
@ -637,6 +637,7 @@ namespace internal {
|
||||
F(LoadGlobalIC_Slow, 3, 1) \
|
||||
F(LoadIC_Miss, 4, 1) \
|
||||
F(LoadPropertyWithInterceptor, 5, 1) \
|
||||
F(StoreInArrayLiteralIC_Slow, 5, 1) \
|
||||
F(StoreCallbackProperty, 6, 1) \
|
||||
F(StoreGlobalIC_Miss, 4, 1) \
|
||||
F(StoreGlobalIC_Slow, 5, 1) \
|
||||
|
@ -35,17 +35,17 @@ bytecodes: [
|
||||
/* 42 S> */ B(LdaSmi), I8(1),
|
||||
B(Star), R(0),
|
||||
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(2),
|
||||
B(Star), R(1),
|
||||
B(LdaZero),
|
||||
B(Star), R(1),
|
||||
B(Star), R(2),
|
||||
B(Ldar), R(0),
|
||||
/* 54 E> */ B(StaKeyedProperty), R(2), R(1), U8(1),
|
||||
/* 54 E> */ B(StaKeyedProperty), R(1), R(2), U8(1),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(1),
|
||||
B(Star), R(2),
|
||||
B(Ldar), R(0),
|
||||
/* 59 E> */ B(AddSmi), I8(1), U8(3),
|
||||
B(StaKeyedProperty), R(2), R(1), U8(1),
|
||||
B(Ldar), R(2),
|
||||
B(StaKeyedProperty), R(1), R(2), U8(1),
|
||||
B(Ldar), R(1),
|
||||
/* 65 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
@ -84,29 +84,29 @@ bytecodes: [
|
||||
/* 42 S> */ B(LdaSmi), I8(1),
|
||||
B(Star), R(0),
|
||||
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(4),
|
||||
B(Star), R(1),
|
||||
B(LdaZero),
|
||||
B(Star), R(2),
|
||||
B(LdaZero),
|
||||
B(Star), R(1),
|
||||
B(CreateArrayLiteral), U8(1), U8(3), U8(37),
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(3),
|
||||
B(LdaZero),
|
||||
B(Star), R(4),
|
||||
B(Ldar), R(0),
|
||||
/* 56 E> */ B(StaKeyedProperty), R(4), R(3), U8(4),
|
||||
B(Ldar), R(4),
|
||||
B(StaKeyedProperty), R(2), R(1), U8(1),
|
||||
/* 56 E> */ B(StaKeyedProperty), R(3), R(4), U8(4),
|
||||
B(Ldar), R(3),
|
||||
B(StaKeyedProperty), R(1), R(2), U8(1),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(1),
|
||||
B(CreateArrayLiteral), U8(2), U8(6), U8(37),
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(Star), R(2),
|
||||
B(CreateArrayLiteral), U8(2), U8(11), U8(37),
|
||||
B(Star), R(3),
|
||||
B(LdaZero),
|
||||
B(Star), R(4),
|
||||
B(Ldar), R(0),
|
||||
/* 68 E> */ B(AddSmi), I8(2), U8(9),
|
||||
B(StaKeyedProperty), R(4), R(3), U8(7),
|
||||
B(Ldar), R(4),
|
||||
B(StaKeyedProperty), R(2), R(1), U8(1),
|
||||
B(Ldar), R(2),
|
||||
/* 68 E> */ B(AddSmi), I8(2), U8(14),
|
||||
B(StaKeyedProperty), R(3), R(4), U8(12),
|
||||
B(Ldar), R(3),
|
||||
B(StaKeyedProperty), R(1), R(2), U8(1),
|
||||
B(Ldar), R(1),
|
||||
/* 76 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -282,23 +282,23 @@ bytecodes: [
|
||||
B(Mov), R(context), R(18),
|
||||
/* 36 S> */ B(CreateArrayLiteral), U8(5), U8(0), U8(37),
|
||||
B(Star), R(19),
|
||||
B(LdaNamedProperty), R(19), U8(6), U8(1),
|
||||
B(LdaNamedProperty), R(19), U8(6), U8(6),
|
||||
B(Star), R(20),
|
||||
B(CallProperty0), R(20), R(19), U8(3),
|
||||
B(CallProperty0), R(20), R(19), U8(8),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(4),
|
||||
/* 36 E> */ B(LdaNamedProperty), R(4), U8(7), U8(5),
|
||||
/* 36 E> */ B(LdaNamedProperty), R(4), U8(7), U8(10),
|
||||
B(Star), R(5),
|
||||
/* 31 S> */ B(CallProperty0), R(5), R(4), U8(7),
|
||||
/* 31 S> */ B(CallProperty0), R(5), R(4), U8(12),
|
||||
B(Star), R(6),
|
||||
/* 31 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(9),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(14),
|
||||
B(JumpIfToBooleanTrue), U8(68),
|
||||
B(LdaNamedProperty), R(6), U8(9), U8(11),
|
||||
B(LdaNamedProperty), R(6), U8(9), U8(16),
|
||||
B(Star), R(8),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(7),
|
||||
@ -334,7 +334,7 @@ bytecodes: [
|
||||
B(Ldar), R(18),
|
||||
B(PushContext), R(19),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(7), U8(13),
|
||||
B(TestEqualStrict), R(7), U8(18),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(7),
|
||||
@ -353,15 +353,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(17),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7), U8(14),
|
||||
B(TestEqualStrict), R(7), U8(19),
|
||||
B(JumpIfTrue), U8(90),
|
||||
B(LdaNamedProperty), R(4), U8(14), U8(15),
|
||||
B(LdaNamedProperty), R(4), U8(14), U8(20),
|
||||
B(Star), R(9),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(79),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(7), U8(17),
|
||||
B(TestEqualStrict), R(7), U8(22),
|
||||
B(JumpIfFalse), U8(47),
|
||||
B(Ldar), R(9),
|
||||
B(TestTypeOf), U8(6),
|
||||
|
@ -20,7 +20,7 @@ bytecodes: [
|
||||
B(Star), R(0),
|
||||
B(CreateArrayLiteral), U8(2), U8(4), U8(37),
|
||||
B(Star), R(2),
|
||||
/* 39 E> */ B(CallWithSpread), R(0), R(1), U8(2), U8(5),
|
||||
/* 39 E> */ B(CallWithSpread), R(0), R(1), U8(2), U8(10),
|
||||
B(LdaUndefined),
|
||||
/* 58 S> */ B(Return),
|
||||
]
|
||||
@ -49,7 +49,7 @@ bytecodes: [
|
||||
B(Star), R(2),
|
||||
B(CreateArrayLiteral), U8(2), U8(4), U8(37),
|
||||
B(Star), R(3),
|
||||
/* 39 E> */ B(CallWithSpread), R(0), R(1), U8(3), U8(5),
|
||||
/* 39 E> */ B(CallWithSpread), R(0), R(1), U8(3), U8(10),
|
||||
B(LdaUndefined),
|
||||
/* 61 S> */ B(Return),
|
||||
]
|
||||
@ -65,9 +65,9 @@ handlers: [
|
||||
snippet: "
|
||||
Math.max(0, ...[1, 2, 3], 4);
|
||||
"
|
||||
frame size: 11
|
||||
frame size: 10
|
||||
parameter count: 1
|
||||
bytecode array length: 109
|
||||
bytecode array length: 112
|
||||
bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 34 S> */ B(LdaGlobal), U8(0), U8(0),
|
||||
@ -75,34 +75,38 @@ bytecodes: [
|
||||
B(LdaNamedProperty), R(0), U8(1), U8(2),
|
||||
B(Star), R(1),
|
||||
B(CreateArrayLiteral), U8(2), U8(4), U8(37),
|
||||
B(Star), R(3),
|
||||
B(LdaConstant), U8(3),
|
||||
B(Star), R(4),
|
||||
/* 49 S> */ B(CreateArrayLiteral), U8(3), U8(5), U8(37),
|
||||
/* 49 S> */ B(CreateArrayLiteral), U8(4), U8(10), U8(37),
|
||||
B(Star), R(8),
|
||||
B(LdaNamedProperty), R(8), U8(5), U8(16),
|
||||
B(Star), R(9),
|
||||
B(LdaNamedProperty), R(9), U8(4), U8(6),
|
||||
B(Star), R(10),
|
||||
B(CallProperty0), R(10), R(9), U8(8),
|
||||
B(CallProperty0), R(9), R(8), U8(18),
|
||||
B(Mov), R(0), R(2),
|
||||
B(Mov), R(4), R(5),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(8),
|
||||
B(LdaNamedProperty), R(8), U8(5), U8(10),
|
||||
B(Star), R(7),
|
||||
B(CallProperty0), R(7), R(8), U8(12),
|
||||
B(LdaNamedProperty), R(7), U8(6), U8(20),
|
||||
B(Star), R(6),
|
||||
B(CallProperty0), R(6), R(7), U8(22),
|
||||
B(Star), R(5),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(6), U8(14),
|
||||
B(JumpIfToBooleanTrue), U8(16),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(16),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kAppendElement), R(5), U8(2),
|
||||
B(JumpLoop), U8(30), I8(0),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
|
||||
B(LdaNamedProperty), R(5), U8(7), U8(24),
|
||||
B(JumpIfToBooleanTrue), U8(21),
|
||||
B(LdaNamedProperty), R(5), U8(8), U8(26),
|
||||
B(Star), R(5),
|
||||
B(StaInArrayLiteral), R(3), R(4), U8(5),
|
||||
B(Ldar), R(4),
|
||||
B(Inc), U8(7),
|
||||
B(Star), R(4),
|
||||
B(JumpLoop), U8(35), I8(0),
|
||||
B(LdaSmi), I8(4),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(4), R(5),
|
||||
B(CallRuntime), U16(Runtime::kAppendElement), R(5), U8(2),
|
||||
B(Mov), R(5), R(3),
|
||||
B(StaInArrayLiteral), R(3), R(4), U8(5),
|
||||
B(Ldar), R(4),
|
||||
B(Inc), U8(7),
|
||||
B(Star), R(4),
|
||||
B(CallJSRuntime), U8(%reflect_apply), R(1), U8(3),
|
||||
B(LdaUndefined),
|
||||
/* 64 S> */ B(Return),
|
||||
@ -111,6 +115,7 @@ constant pool: [
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["Math"],
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["max"],
|
||||
TUPLE2_TYPE,
|
||||
Smi [1],
|
||||
TUPLE2_TYPE,
|
||||
SYMBOL_TYPE,
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
|
||||
|
@ -270,13 +270,13 @@ bytecodes: [
|
||||
/* 55 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(1),
|
||||
/* 63 S> */ B(Ldar), R(0),
|
||||
B(ToNumeric), U8(1),
|
||||
B(ToNumeric), U8(6),
|
||||
B(Star), R(3),
|
||||
B(Inc), U8(1),
|
||||
B(Inc), U8(6),
|
||||
B(Star), R(0),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(4),
|
||||
/* 79 E> */ B(StaKeyedProperty), R(1), R(3), U8(2),
|
||||
/* 79 E> */ B(StaKeyedProperty), R(1), R(3), U8(7),
|
||||
B(Ldar), R(4),
|
||||
/* 83 S> */ B(Return),
|
||||
]
|
||||
|
@ -34,22 +34,22 @@ bytecodes: [
|
||||
B(Mov), R(context), R(19),
|
||||
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
|
||||
B(Star), R(20),
|
||||
B(LdaNamedProperty), R(20), U8(4), U8(1),
|
||||
B(LdaNamedProperty), R(20), U8(4), U8(6),
|
||||
B(JumpIfUndefined), U8(17),
|
||||
B(JumpIfNull), U8(15),
|
||||
B(Star), R(21),
|
||||
B(CallProperty0), R(21), R(20), U8(3),
|
||||
B(CallProperty0), R(21), R(20), U8(8),
|
||||
B(JumpIfJSReceiver), U8(23),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
|
||||
B(LdaNamedProperty), R(20), U8(5), U8(5),
|
||||
B(LdaNamedProperty), R(20), U8(5), U8(10),
|
||||
B(Star), R(21),
|
||||
B(CallProperty0), R(21), R(20), U8(7),
|
||||
B(CallProperty0), R(21), R(20), U8(12),
|
||||
B(Star), R(21),
|
||||
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(21), U8(1),
|
||||
B(Star), R(4),
|
||||
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(9),
|
||||
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(14),
|
||||
B(Star), R(5),
|
||||
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(11),
|
||||
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(16),
|
||||
B(Star), R(21),
|
||||
B(Mov), R(2), R(20),
|
||||
B(Mov), R(11), R(22),
|
||||
@ -69,9 +69,9 @@ bytecodes: [
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(13),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(18),
|
||||
B(JumpIfToBooleanTrue), U8(25),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(15),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(20),
|
||||
B(Star), R(8),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(7),
|
||||
@ -91,7 +91,7 @@ bytecodes: [
|
||||
B(Ldar), R(19),
|
||||
B(PushContext), R(20),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(7), U8(17),
|
||||
B(TestEqualStrict), R(7), U8(22),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(7),
|
||||
@ -110,15 +110,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(18),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7), U8(18),
|
||||
B(TestEqualStrict), R(7), U8(23),
|
||||
B(JumpIfTrue), U8(167),
|
||||
B(LdaNamedProperty), R(4), U8(11), U8(19),
|
||||
B(LdaNamedProperty), R(4), U8(11), U8(24),
|
||||
B(Star), R(9),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(156),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(7), U8(21),
|
||||
B(TestEqualStrict), R(7), U8(26),
|
||||
B(JumpIfFalse), U8(86),
|
||||
B(Ldar), R(9),
|
||||
B(TestTypeOf), U8(6),
|
||||
@ -287,22 +287,22 @@ bytecodes: [
|
||||
B(Mov), R(context), R(19),
|
||||
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
|
||||
B(Star), R(20),
|
||||
B(LdaNamedProperty), R(20), U8(4), U8(1),
|
||||
B(LdaNamedProperty), R(20), U8(4), U8(6),
|
||||
B(JumpIfUndefined), U8(17),
|
||||
B(JumpIfNull), U8(15),
|
||||
B(Star), R(21),
|
||||
B(CallProperty0), R(21), R(20), U8(3),
|
||||
B(CallProperty0), R(21), R(20), U8(8),
|
||||
B(JumpIfJSReceiver), U8(23),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
|
||||
B(LdaNamedProperty), R(20), U8(5), U8(5),
|
||||
B(LdaNamedProperty), R(20), U8(5), U8(10),
|
||||
B(Star), R(21),
|
||||
B(CallProperty0), R(21), R(20), U8(7),
|
||||
B(CallProperty0), R(21), R(20), U8(12),
|
||||
B(Star), R(21),
|
||||
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(21), U8(1),
|
||||
B(Star), R(4),
|
||||
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(9),
|
||||
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(14),
|
||||
B(Star), R(5),
|
||||
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(11),
|
||||
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(16),
|
||||
B(Star), R(21),
|
||||
B(Mov), R(2), R(20),
|
||||
B(Mov), R(11), R(22),
|
||||
@ -322,9 +322,9 @@ bytecodes: [
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(13),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(18),
|
||||
B(JumpIfToBooleanTrue), U8(27),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(15),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(20),
|
||||
B(Star), R(8),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(7),
|
||||
@ -345,7 +345,7 @@ bytecodes: [
|
||||
B(Ldar), R(19),
|
||||
B(PushContext), R(20),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(7), U8(17),
|
||||
B(TestEqualStrict), R(7), U8(22),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(7),
|
||||
@ -364,15 +364,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(18),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7), U8(18),
|
||||
B(TestEqualStrict), R(7), U8(23),
|
||||
B(JumpIfTrue), U8(167),
|
||||
B(LdaNamedProperty), R(4), U8(11), U8(19),
|
||||
B(LdaNamedProperty), R(4), U8(11), U8(24),
|
||||
B(Star), R(9),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(156),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(7), U8(21),
|
||||
B(TestEqualStrict), R(7), U8(26),
|
||||
B(JumpIfFalse), U8(86),
|
||||
B(Ldar), R(9),
|
||||
B(TestTypeOf), U8(6),
|
||||
@ -556,22 +556,22 @@ bytecodes: [
|
||||
B(Mov), R(context), R(19),
|
||||
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
|
||||
B(Star), R(20),
|
||||
B(LdaNamedProperty), R(20), U8(4), U8(1),
|
||||
B(LdaNamedProperty), R(20), U8(4), U8(6),
|
||||
B(JumpIfUndefined), U8(17),
|
||||
B(JumpIfNull), U8(15),
|
||||
B(Star), R(21),
|
||||
B(CallProperty0), R(21), R(20), U8(3),
|
||||
B(CallProperty0), R(21), R(20), U8(8),
|
||||
B(JumpIfJSReceiver), U8(23),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
|
||||
B(LdaNamedProperty), R(20), U8(5), U8(5),
|
||||
B(LdaNamedProperty), R(20), U8(5), U8(10),
|
||||
B(Star), R(21),
|
||||
B(CallProperty0), R(21), R(20), U8(7),
|
||||
B(CallProperty0), R(21), R(20), U8(12),
|
||||
B(Star), R(21),
|
||||
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(21), U8(1),
|
||||
B(Star), R(4),
|
||||
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(9),
|
||||
/* 43 E> */ B(LdaNamedProperty), R(4), U8(6), U8(14),
|
||||
B(Star), R(5),
|
||||
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(11),
|
||||
/* 40 S> */ B(CallProperty0), R(5), R(4), U8(16),
|
||||
B(Star), R(21),
|
||||
B(Mov), R(2), R(20),
|
||||
B(Mov), R(11), R(22),
|
||||
@ -591,9 +591,9 @@ bytecodes: [
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(13),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(18),
|
||||
B(JumpIfToBooleanTrue), U8(43),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(15),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(20),
|
||||
B(Star), R(8),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(7),
|
||||
@ -601,11 +601,11 @@ bytecodes: [
|
||||
/* 23 E> */ B(StackCheck),
|
||||
B(Mov), R(3), R(0),
|
||||
/* 63 S> */ B(LdaSmi), I8(10),
|
||||
/* 69 E> */ B(TestEqual), R(0), U8(17),
|
||||
/* 69 E> */ B(TestEqual), R(0), U8(22),
|
||||
B(JumpIfFalse), U8(4),
|
||||
/* 76 S> */ B(Jump), U8(14),
|
||||
/* 90 S> */ B(LdaSmi), I8(20),
|
||||
/* 96 E> */ B(TestEqual), R(0), U8(18),
|
||||
/* 96 E> */ B(TestEqual), R(0), U8(23),
|
||||
B(JumpIfFalse), U8(4),
|
||||
/* 103 S> */ B(Jump), U8(8),
|
||||
B(LdaZero),
|
||||
@ -621,7 +621,7 @@ bytecodes: [
|
||||
B(Ldar), R(19),
|
||||
B(PushContext), R(20),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(7), U8(19),
|
||||
B(TestEqualStrict), R(7), U8(24),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(7),
|
||||
@ -640,15 +640,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(18),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7), U8(20),
|
||||
B(TestEqualStrict), R(7), U8(25),
|
||||
B(JumpIfTrue), U8(167),
|
||||
B(LdaNamedProperty), R(4), U8(11), U8(21),
|
||||
B(LdaNamedProperty), R(4), U8(11), U8(26),
|
||||
B(Star), R(9),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(156),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(7), U8(23),
|
||||
B(TestEqualStrict), R(7), U8(28),
|
||||
B(JumpIfFalse), U8(86),
|
||||
B(Ldar), R(9),
|
||||
B(TestTypeOf), U8(6),
|
||||
@ -815,30 +815,30 @@ bytecodes: [
|
||||
B(Mov), R(context), R(17),
|
||||
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
|
||||
B(Star), R(18),
|
||||
B(LdaNamedProperty), R(18), U8(2), U8(2),
|
||||
B(LdaNamedProperty), R(18), U8(2), U8(7),
|
||||
B(Star), R(19),
|
||||
B(CallProperty0), R(19), R(18), U8(4),
|
||||
B(CallProperty0), R(19), R(18), U8(9),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(2),
|
||||
/* 68 E> */ B(LdaNamedProperty), R(2), U8(3), U8(6),
|
||||
/* 68 E> */ B(LdaNamedProperty), R(2), U8(3), U8(11),
|
||||
B(Star), R(3),
|
||||
/* 59 S> */ B(CallProperty0), R(3), R(2), U8(8),
|
||||
/* 59 S> */ B(CallProperty0), R(3), R(2), U8(13),
|
||||
B(Star), R(4),
|
||||
/* 59 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
|
||||
B(LdaNamedProperty), R(4), U8(4), U8(10),
|
||||
B(LdaNamedProperty), R(4), U8(4), U8(15),
|
||||
B(JumpIfToBooleanTrue), U8(30),
|
||||
/* 58 E> */ B(LdaNamedProperty), R(4), U8(5), U8(12),
|
||||
/* 58 E> */ B(LdaNamedProperty), R(4), U8(5), U8(17),
|
||||
B(Star), R(6),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(5),
|
||||
B(Ldar), R(6),
|
||||
B(StaNamedProperty), R(1), U8(6), U8(14),
|
||||
B(StaNamedProperty), R(1), U8(6), U8(19),
|
||||
/* 53 E> */ B(StackCheck),
|
||||
/* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(16),
|
||||
/* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(21),
|
||||
B(Star), R(15),
|
||||
B(LdaZero),
|
||||
B(Star), R(14),
|
||||
@ -853,7 +853,7 @@ bytecodes: [
|
||||
B(Ldar), R(17),
|
||||
B(PushContext), R(18),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(5), U8(18),
|
||||
B(TestEqualStrict), R(5), U8(23),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(5),
|
||||
@ -872,15 +872,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(16),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(5), U8(19),
|
||||
B(TestEqualStrict), R(5), U8(24),
|
||||
B(JumpIfTrue), U8(90),
|
||||
B(LdaNamedProperty), R(2), U8(9), U8(20),
|
||||
B(LdaNamedProperty), R(2), U8(9), U8(25),
|
||||
B(Star), R(7),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(79),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(5), U8(22),
|
||||
B(TestEqualStrict), R(5), U8(27),
|
||||
B(JumpIfFalse), U8(47),
|
||||
B(Ldar), R(7),
|
||||
B(TestTypeOf), U8(6),
|
||||
|
@ -123,7 +123,7 @@ bytecodes: [
|
||||
/* 45 E> */ B(StackCheck),
|
||||
B(Star), R(2),
|
||||
/* 70 S> */ B(Ldar), R(1),
|
||||
/* 75 E> */ B(Add), R(0), U8(2),
|
||||
/* 75 E> */ B(Add), R(0), U8(7),
|
||||
B(Mov), R(0), R(8),
|
||||
B(Star), R(0),
|
||||
/* 72 E> */ B(ForInStep), R(7),
|
||||
@ -167,18 +167,18 @@ bytecodes: [
|
||||
B(JumpIfUndefined), U8(41),
|
||||
B(Star), R(6),
|
||||
B(Ldar), R(6),
|
||||
/* 67 E> */ B(StaNamedProperty), R(0), U8(2), U8(3),
|
||||
/* 67 E> */ B(StaNamedProperty), R(0), U8(2), U8(8),
|
||||
/* 62 E> */ B(StackCheck),
|
||||
/* 100 S> */ B(LdaNamedProperty), R(0), U8(2), U8(5),
|
||||
/* 100 S> */ B(LdaNamedProperty), R(0), U8(2), U8(10),
|
||||
B(Star), R(6),
|
||||
B(LdaSmi), I8(10),
|
||||
/* 106 E> */ B(TestEqual), R(6), U8(7),
|
||||
/* 106 E> */ B(TestEqual), R(6), U8(12),
|
||||
B(JumpIfFalse), U8(4),
|
||||
/* 113 S> */ B(Jump), U8(17),
|
||||
/* 130 S> */ B(LdaNamedProperty), R(0), U8(2), U8(8),
|
||||
/* 130 S> */ B(LdaNamedProperty), R(0), U8(2), U8(13),
|
||||
B(Star), R(6),
|
||||
B(LdaSmi), I8(20),
|
||||
/* 136 E> */ B(TestEqual), R(6), U8(10),
|
||||
/* 136 E> */ B(TestEqual), R(6), U8(15),
|
||||
B(JumpIfFalse), U8(4),
|
||||
/* 143 S> */ B(Jump), U8(9),
|
||||
B(ForInStep), R(5),
|
||||
@ -207,26 +207,26 @@ bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(0),
|
||||
/* 72 S> */ B(CreateArrayLiteral), U8(1), U8(2), U8(37),
|
||||
/* 72 S> */ B(CreateArrayLiteral), U8(1), U8(7), U8(37),
|
||||
B(JumpIfUndefined), U8(51),
|
||||
B(JumpIfNull), U8(49),
|
||||
B(ToObject), R(1),
|
||||
B(ForInEnumerate), R(1),
|
||||
B(ForInPrepare), R(2), U8(1),
|
||||
B(ForInPrepare), R(2), U8(6),
|
||||
B(LdaZero),
|
||||
B(Star), R(5),
|
||||
/* 65 S> */ B(ForInContinue), R(5), R(4),
|
||||
B(JumpIfFalse), U8(34),
|
||||
B(ForInNext), R(1), R(5), R(2), U8(1),
|
||||
B(ForInNext), R(1), R(5), R(2), U8(6),
|
||||
B(JumpIfUndefined), U8(20),
|
||||
B(Star), R(6),
|
||||
B(LdaZero),
|
||||
B(Star), R(8),
|
||||
B(Ldar), R(6),
|
||||
/* 64 E> */ B(StaKeyedProperty), R(0), R(8), U8(3),
|
||||
/* 64 E> */ B(StaKeyedProperty), R(0), R(8), U8(13),
|
||||
/* 59 E> */ B(StackCheck),
|
||||
/* 83 S> */ B(LdaSmi), I8(3),
|
||||
/* 91 E> */ B(LdaKeyedProperty), R(0), U8(5),
|
||||
/* 91 E> */ B(LdaKeyedProperty), R(0), U8(15),
|
||||
/* 95 S> */ B(Return),
|
||||
B(ForInStep), R(5),
|
||||
B(Star), R(5),
|
||||
|
@ -20,23 +20,23 @@ bytecodes: [
|
||||
B(Mov), R(context), R(12),
|
||||
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(13),
|
||||
B(LdaNamedProperty), R(13), U8(1), U8(1),
|
||||
B(LdaNamedProperty), R(13), U8(1), U8(6),
|
||||
B(Star), R(14),
|
||||
B(CallProperty0), R(14), R(13), U8(3),
|
||||
B(CallProperty0), R(14), R(13), U8(8),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(2),
|
||||
/* 48 E> */ B(LdaNamedProperty), R(2), U8(2), U8(5),
|
||||
/* 48 E> */ B(LdaNamedProperty), R(2), U8(2), U8(10),
|
||||
B(Star), R(3),
|
||||
/* 43 S> */ B(CallProperty0), R(3), R(2), U8(7),
|
||||
/* 43 S> */ B(CallProperty0), R(3), R(2), U8(12),
|
||||
B(Star), R(4),
|
||||
/* 43 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
|
||||
B(LdaNamedProperty), R(4), U8(3), U8(9),
|
||||
B(LdaNamedProperty), R(4), U8(3), U8(14),
|
||||
B(JumpIfToBooleanTrue), U8(25),
|
||||
B(LdaNamedProperty), R(4), U8(4), U8(11),
|
||||
B(LdaNamedProperty), R(4), U8(4), U8(16),
|
||||
B(Star), R(6),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(5),
|
||||
@ -53,7 +53,7 @@ bytecodes: [
|
||||
B(PushContext), R(13),
|
||||
B(Star), R(12),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(5), U8(13),
|
||||
B(TestEqualStrict), R(5), U8(18),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(5),
|
||||
@ -72,15 +72,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(11),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(5), U8(14),
|
||||
B(TestEqualStrict), R(5), U8(19),
|
||||
B(JumpIfTrue), U8(90),
|
||||
B(LdaNamedProperty), R(2), U8(7), U8(15),
|
||||
B(LdaNamedProperty), R(2), U8(7), U8(20),
|
||||
B(Star), R(7),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(79),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(5), U8(17),
|
||||
B(TestEqualStrict), R(5), U8(22),
|
||||
B(JumpIfFalse), U8(47),
|
||||
B(Ldar), R(7),
|
||||
B(TestTypeOf), U8(6),
|
||||
@ -292,23 +292,23 @@ bytecodes: [
|
||||
B(Mov), R(context), R(12),
|
||||
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(13),
|
||||
B(LdaNamedProperty), R(13), U8(1), U8(1),
|
||||
B(LdaNamedProperty), R(13), U8(1), U8(6),
|
||||
B(Star), R(14),
|
||||
B(CallProperty0), R(14), R(13), U8(3),
|
||||
B(CallProperty0), R(14), R(13), U8(8),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(2),
|
||||
/* 48 E> */ B(LdaNamedProperty), R(2), U8(2), U8(5),
|
||||
/* 48 E> */ B(LdaNamedProperty), R(2), U8(2), U8(10),
|
||||
B(Star), R(3),
|
||||
/* 43 S> */ B(CallProperty0), R(3), R(2), U8(7),
|
||||
/* 43 S> */ B(CallProperty0), R(3), R(2), U8(12),
|
||||
B(Star), R(4),
|
||||
/* 43 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
|
||||
B(LdaNamedProperty), R(4), U8(3), U8(9),
|
||||
B(LdaNamedProperty), R(4), U8(3), U8(14),
|
||||
B(JumpIfToBooleanTrue), U8(43),
|
||||
B(LdaNamedProperty), R(4), U8(4), U8(11),
|
||||
B(LdaNamedProperty), R(4), U8(4), U8(16),
|
||||
B(Star), R(6),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(5),
|
||||
@ -316,11 +316,11 @@ bytecodes: [
|
||||
/* 34 E> */ B(StackCheck),
|
||||
B(Mov), R(0), R(1),
|
||||
/* 66 S> */ B(LdaSmi), I8(10),
|
||||
/* 72 E> */ B(TestEqual), R(1), U8(13),
|
||||
/* 72 E> */ B(TestEqual), R(1), U8(18),
|
||||
B(JumpIfFalse), U8(4),
|
||||
/* 79 S> */ B(Jump), U8(14),
|
||||
/* 91 S> */ B(LdaSmi), I8(20),
|
||||
/* 97 E> */ B(TestEqual), R(1), U8(14),
|
||||
/* 97 E> */ B(TestEqual), R(1), U8(19),
|
||||
B(JumpIfFalse), U8(4),
|
||||
/* 104 S> */ B(Jump), U8(8),
|
||||
B(LdaZero),
|
||||
@ -333,7 +333,7 @@ bytecodes: [
|
||||
B(PushContext), R(13),
|
||||
B(Star), R(12),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(5), U8(15),
|
||||
B(TestEqualStrict), R(5), U8(20),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(5),
|
||||
@ -352,15 +352,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(11),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(5), U8(16),
|
||||
B(TestEqualStrict), R(5), U8(21),
|
||||
B(JumpIfTrue), U8(90),
|
||||
B(LdaNamedProperty), R(2), U8(7), U8(17),
|
||||
B(LdaNamedProperty), R(2), U8(7), U8(22),
|
||||
B(Star), R(7),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(79),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(5), U8(19),
|
||||
B(TestEqualStrict), R(5), U8(24),
|
||||
B(JumpIfFalse), U8(47),
|
||||
B(Ldar), R(7),
|
||||
B(TestTypeOf), U8(6),
|
||||
@ -434,30 +434,30 @@ bytecodes: [
|
||||
B(Mov), R(context), R(11),
|
||||
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
|
||||
B(Star), R(12),
|
||||
B(LdaNamedProperty), R(12), U8(2), U8(2),
|
||||
B(LdaNamedProperty), R(12), U8(2), U8(7),
|
||||
B(Star), R(13),
|
||||
B(CallProperty0), R(13), R(12), U8(4),
|
||||
B(CallProperty0), R(13), R(12), U8(9),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(1),
|
||||
/* 77 E> */ B(LdaNamedProperty), R(1), U8(3), U8(6),
|
||||
/* 77 E> */ B(LdaNamedProperty), R(1), U8(3), U8(11),
|
||||
B(Star), R(2),
|
||||
/* 68 S> */ B(CallProperty0), R(2), R(1), U8(8),
|
||||
/* 68 S> */ B(CallProperty0), R(2), R(1), U8(13),
|
||||
B(Star), R(3),
|
||||
/* 68 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
|
||||
B(LdaNamedProperty), R(3), U8(4), U8(10),
|
||||
B(LdaNamedProperty), R(3), U8(4), U8(15),
|
||||
B(JumpIfToBooleanTrue), U8(30),
|
||||
/* 67 E> */ B(LdaNamedProperty), R(3), U8(5), U8(12),
|
||||
/* 67 E> */ B(LdaNamedProperty), R(3), U8(5), U8(17),
|
||||
B(Star), R(5),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(StaNamedProperty), R(0), U8(6), U8(14),
|
||||
B(StaNamedProperty), R(0), U8(6), U8(19),
|
||||
/* 62 E> */ B(StackCheck),
|
||||
/* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(16),
|
||||
/* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(21),
|
||||
B(Star), R(9),
|
||||
B(LdaZero),
|
||||
B(Star), R(8),
|
||||
@ -469,7 +469,7 @@ bytecodes: [
|
||||
B(PushContext), R(12),
|
||||
B(Star), R(11),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(4), U8(18),
|
||||
B(TestEqualStrict), R(4), U8(23),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(4),
|
||||
@ -488,15 +488,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(10),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(4), U8(19),
|
||||
B(TestEqualStrict), R(4), U8(24),
|
||||
B(JumpIfTrue), U8(90),
|
||||
B(LdaNamedProperty), R(1), U8(9), U8(20),
|
||||
B(LdaNamedProperty), R(1), U8(9), U8(25),
|
||||
B(Star), R(6),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(79),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(4), U8(22),
|
||||
B(TestEqualStrict), R(4), U8(27),
|
||||
B(JumpIfFalse), U8(47),
|
||||
B(Ldar), R(6),
|
||||
B(TestTypeOf), U8(6),
|
||||
|
@ -123,23 +123,23 @@ bytecodes: [
|
||||
B(Mov), R(context), R(14),
|
||||
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
|
||||
B(Star), R(15),
|
||||
B(LdaNamedProperty), R(15), U8(5), U8(1),
|
||||
B(LdaNamedProperty), R(15), U8(5), U8(6),
|
||||
B(Star), R(16),
|
||||
B(CallProperty0), R(16), R(15), U8(3),
|
||||
B(CallProperty0), R(16), R(15), U8(8),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(4),
|
||||
/* 30 E> */ B(LdaNamedProperty), R(4), U8(6), U8(5),
|
||||
/* 30 E> */ B(LdaNamedProperty), R(4), U8(6), U8(10),
|
||||
B(Star), R(5),
|
||||
/* 25 S> */ B(CallProperty0), R(5), R(4), U8(7),
|
||||
/* 25 S> */ B(CallProperty0), R(5), R(4), U8(12),
|
||||
B(Star), R(6),
|
||||
/* 25 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
|
||||
B(ToBooleanLogicalNot),
|
||||
B(JumpIfFalse), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(9),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(14),
|
||||
B(JumpIfToBooleanTrue), U8(65),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(11),
|
||||
B(LdaNamedProperty), R(6), U8(8), U8(16),
|
||||
B(Star), R(8),
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(7),
|
||||
@ -171,7 +171,7 @@ bytecodes: [
|
||||
B(PushContext), R(15),
|
||||
B(Star), R(14),
|
||||
B(LdaSmi), I8(2),
|
||||
B(TestEqualStrict), R(7), U8(13),
|
||||
B(TestEqualStrict), R(7), U8(18),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(7),
|
||||
@ -190,15 +190,15 @@ bytecodes: [
|
||||
B(SetPendingMessage),
|
||||
B(Star), R(13),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(7), U8(14),
|
||||
B(TestEqualStrict), R(7), U8(19),
|
||||
B(JumpIfTrue), U8(90),
|
||||
B(LdaNamedProperty), R(4), U8(13), U8(15),
|
||||
B(LdaNamedProperty), R(4), U8(13), U8(20),
|
||||
B(Star), R(9),
|
||||
B(TestUndetectable),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(79),
|
||||
B(LdaSmi), I8(1),
|
||||
B(TestEqualStrict), R(7), U8(17),
|
||||
B(TestEqualStrict), R(7), U8(22),
|
||||
B(JumpIfFalse), U8(47),
|
||||
B(Ldar), R(9),
|
||||
B(TestTypeOf), U8(6),
|
||||
|
@ -29,7 +29,7 @@ bytecodes: [
|
||||
/* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(1),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(2), R(3), U8(1), U8(2),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(2), R(3), U8(1), U8(7),
|
||||
B(LdaUndefined),
|
||||
/* 110 S> */ B(Return),
|
||||
]
|
||||
@ -67,7 +67,7 @@ bytecodes: [
|
||||
B(CreateArrayLiteral), U8(2), U8(1), U8(37),
|
||||
B(Star), R(4),
|
||||
B(Ldar), R(1),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(2), R(3), U8(2), U8(2),
|
||||
/* 89 E> */ B(ConstructWithSpread), R(2), R(3), U8(2), U8(7),
|
||||
B(LdaUndefined),
|
||||
/* 113 S> */ B(Return),
|
||||
]
|
||||
@ -84,9 +84,9 @@ snippet: "
|
||||
class A { constructor(...args) { this.args = args; } }
|
||||
new A(0, ...[1, 2, 3], 4);
|
||||
"
|
||||
frame size: 11
|
||||
frame size: 10
|
||||
parameter count: 1
|
||||
bytecode array length: 124
|
||||
bytecode array length: 127
|
||||
bytecodes: [
|
||||
/* 30 E> */ B(StackCheck),
|
||||
B(LdaTheHole),
|
||||
@ -101,33 +101,37 @@ bytecodes: [
|
||||
B(Mov), R(4), R(0),
|
||||
B(Mov), R(0), R(1),
|
||||
/* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37),
|
||||
B(Star), R(3),
|
||||
B(LdaConstant), U8(3),
|
||||
B(Star), R(4),
|
||||
/* 101 S> */ B(CreateArrayLiteral), U8(3), U8(2), U8(37),
|
||||
/* 101 S> */ B(CreateArrayLiteral), U8(4), U8(7), U8(37),
|
||||
B(Star), R(8),
|
||||
B(LdaNamedProperty), R(8), U8(5), U8(13),
|
||||
B(Star), R(9),
|
||||
B(LdaNamedProperty), R(9), U8(4), U8(3),
|
||||
B(Star), R(10),
|
||||
B(CallProperty0), R(10), R(9), U8(5),
|
||||
B(Mov), R(4), R(5),
|
||||
B(CallProperty0), R(9), R(8), U8(15),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(8),
|
||||
B(LdaNamedProperty), R(8), U8(5), U8(7),
|
||||
B(Star), R(7),
|
||||
B(CallProperty0), R(7), R(8), U8(9),
|
||||
B(LdaNamedProperty), R(7), U8(6), U8(17),
|
||||
B(Star), R(6),
|
||||
B(CallProperty0), R(6), R(7), U8(19),
|
||||
B(Star), R(5),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
|
||||
B(LdaNamedProperty), R(6), U8(6), U8(11),
|
||||
B(JumpIfToBooleanTrue), U8(16),
|
||||
B(LdaNamedProperty), R(6), U8(7), U8(13),
|
||||
B(Star), R(6),
|
||||
B(CallRuntime), U16(Runtime::kAppendElement), R(5), U8(2),
|
||||
B(JumpLoop), U8(30), I8(0),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
|
||||
B(LdaNamedProperty), R(5), U8(7), U8(21),
|
||||
B(JumpIfToBooleanTrue), U8(21),
|
||||
B(LdaNamedProperty), R(5), U8(8), U8(23),
|
||||
B(Star), R(5),
|
||||
B(StaInArrayLiteral), R(3), R(4), U8(2),
|
||||
B(Ldar), R(4),
|
||||
B(Inc), U8(4),
|
||||
B(Star), R(4),
|
||||
B(JumpLoop), U8(35), I8(0),
|
||||
B(LdaSmi), I8(4),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(4), R(5),
|
||||
B(CallRuntime), U16(Runtime::kAppendElement), R(5), U8(2),
|
||||
B(Mov), R(5), R(3),
|
||||
B(StaInArrayLiteral), R(3), R(4), U8(2),
|
||||
B(Ldar), R(4),
|
||||
B(Inc), U8(4),
|
||||
B(Star), R(4),
|
||||
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
|
||||
B(LdaUndefined),
|
||||
/* 116 S> */ B(Return),
|
||||
@ -136,6 +140,7 @@ constant pool: [
|
||||
FIXED_ARRAY_TYPE,
|
||||
SHARED_FUNCTION_INFO_TYPE,
|
||||
TUPLE2_TYPE,
|
||||
Smi [1],
|
||||
TUPLE2_TYPE,
|
||||
SYMBOL_TYPE,
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
|
||||
|
@ -91,9 +91,9 @@ snippet: "
|
||||
test = new B(1, 2, 3).constructor;
|
||||
})();
|
||||
"
|
||||
frame size: 13
|
||||
frame size: 12
|
||||
parameter count: 1
|
||||
bytecode array length: 121
|
||||
bytecode array length: 124
|
||||
bytecodes: [
|
||||
B(CreateRestParameter),
|
||||
B(Star), R(2),
|
||||
@ -103,32 +103,36 @@ bytecodes: [
|
||||
/* 140 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(closure), U8(1),
|
||||
B(Star), R(4),
|
||||
B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(5),
|
||||
B(LdaConstant), U8(1),
|
||||
/* 152 S> */ B(Star), R(6),
|
||||
B(LdaNamedProperty), R(2), U8(1), U8(1),
|
||||
B(Star), R(12),
|
||||
B(CallProperty0), R(12), R(2), U8(3),
|
||||
B(Mov), R(2), R(11),
|
||||
B(Mov), R(6), R(7),
|
||||
B(LdaNamedProperty), R(2), U8(2), U8(6),
|
||||
B(Star), R(11),
|
||||
B(CallProperty0), R(11), R(2), U8(8),
|
||||
B(Mov), R(2), R(10),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
|
||||
B(Star), R(10),
|
||||
B(LdaNamedProperty), R(10), U8(2), U8(5),
|
||||
B(Star), R(9),
|
||||
B(CallProperty0), R(9), R(10), U8(7),
|
||||
B(LdaNamedProperty), R(9), U8(3), U8(10),
|
||||
B(Star), R(8),
|
||||
B(CallProperty0), R(8), R(9), U8(12),
|
||||
B(Star), R(7),
|
||||
B(JumpIfJSReceiver), U8(7),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
|
||||
B(LdaNamedProperty), R(8), U8(3), U8(9),
|
||||
B(JumpIfToBooleanTrue), U8(16),
|
||||
B(LdaNamedProperty), R(8), U8(4), U8(11),
|
||||
B(Star), R(8),
|
||||
B(CallRuntime), U16(Runtime::kAppendElement), R(7), U8(2),
|
||||
B(JumpLoop), U8(30), I8(0),
|
||||
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
|
||||
B(LdaNamedProperty), R(7), U8(4), U8(14),
|
||||
B(JumpIfToBooleanTrue), U8(21),
|
||||
B(LdaNamedProperty), R(7), U8(5), U8(16),
|
||||
B(Star), R(7),
|
||||
B(StaInArrayLiteral), R(5), R(6), U8(1),
|
||||
B(Ldar), R(6),
|
||||
B(Inc), U8(3),
|
||||
B(Star), R(6),
|
||||
B(JumpLoop), U8(35), I8(0),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(8),
|
||||
B(Mov), R(6), R(7),
|
||||
B(CallRuntime), U16(Runtime::kAppendElement), R(7), U8(2),
|
||||
B(Mov), R(7), R(5),
|
||||
B(StaInArrayLiteral), R(5), R(6), U8(1),
|
||||
B(Ldar), R(6),
|
||||
B(Inc), U8(3),
|
||||
B(Star), R(6),
|
||||
B(Mov), R(0), R(6),
|
||||
/* 140 E> */ B(CallJSRuntime), U8(%reflect_construct), R(4), U8(3),
|
||||
B(Star), R(4),
|
||||
@ -141,6 +145,7 @@ bytecodes: [
|
||||
]
|
||||
constant pool: [
|
||||
TUPLE2_TYPE,
|
||||
Smi [1],
|
||||
SYMBOL_TYPE,
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
|
||||
|
273
test/mjsunit/es6/spread-array-misc.js
Normal file
273
test/mjsunit/es6/spread-array-misc.js
Normal file
@ -0,0 +1,273 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --expose-gc --allow-natives-syntax
|
||||
|
||||
"use strict";
|
||||
{
|
||||
|
||||
|
||||
// We use g(a, b, c) instead of [a, b, c] when we care about Sminess being
|
||||
// preserved.
|
||||
function* g(...args) { for (const x of args) yield x; }
|
||||
// G is like g but triggers GC to avoid allocation-site updates.
|
||||
function* G(...args) { gc(); for (const x of args) { gc(); yield x; }; gc(); }
|
||||
|
||||
|
||||
assertEquals([], [...[]]);
|
||||
assertEquals([], [...[], ]);
|
||||
assertEquals([1], [1, ...[]]);
|
||||
assertEquals([1, 2], [1, ...[], 2]);
|
||||
assertEquals([, ], [, ...[]]);
|
||||
assertEquals([, ], [, ...[], ]);
|
||||
assertEquals([, ], [, ...[],...[]]);
|
||||
assertEquals([, ], [, ...[],...[], ]);
|
||||
assertEquals([1, 2, 3], [...[1, 2, 3]]);
|
||||
assertEquals([1, 1.5], [...g(1, 1.5)]);
|
||||
assertEquals([, 1, 1.5], [, ...g(1, 1.5)]);
|
||||
assertEquals([1, 2, 2.5, 3.5], [...g(1, 2, 2.5, 3.5)]);
|
||||
assertEquals([2.5, 1, 3.5, 4], [...g(2.5, 1, 3.5, 4)]);
|
||||
assertEquals([2.5, 3.5, 1, 4], [...g(2.5, 3.5, 1, 4)]);
|
||||
assertEquals([{a: 1}, {b: 2}], [...[{a: 1}, {b: 2}]]);
|
||||
assertEquals([0, {a: 1}, {b: 2}], [...g(0, {a: 1}, {b: 2})]);
|
||||
assertEquals([1, 1.5, "2"], [...g(1, 1.5, "2")]);
|
||||
|
||||
|
||||
function f1(x) {
|
||||
return [...[x, x, x]];
|
||||
}
|
||||
assertEquals([1, 1, 1], f1(1));
|
||||
assertEquals([0.1, 0.1, 0.1], f1(0.1));
|
||||
assertEquals([{}, {}, {}], f1({}));
|
||||
assertEquals([1, 1, 1], f1(1));
|
||||
|
||||
function f1_(x) {
|
||||
return [...[x, x, x]];
|
||||
}
|
||||
assertEquals([1, 1, 1], f1_(1));
|
||||
%OptimizeFunctionOnNextCall(f1_);
|
||||
assertEquals([1, 1, 1], f1_(1));
|
||||
assertEquals([0.1, 0.1, 0.1], f1_(0.1));
|
||||
assertEquals([{}, {}, {}], f1_({}));
|
||||
assertEquals([1, 1, 1], f1_(1));
|
||||
|
||||
|
||||
function f2(x) {
|
||||
return [...[x, x, x], ,];
|
||||
}
|
||||
assertEquals([1, 1, 1, ,], f2(1));
|
||||
assertEquals([0.1, 0.1, 0.1, ,], f2(0.1));
|
||||
assertEquals([{}, {}, {}, ,], f2({}));
|
||||
assertEquals([1, 1, 1, ,], f2(1));
|
||||
|
||||
function f2_(x) {
|
||||
return [...[x, x, x], ,];
|
||||
}
|
||||
assertEquals([1, 1, 1, ,], f2_(1));
|
||||
%OptimizeFunctionOnNextCall(f2_);
|
||||
assertEquals([1, 1, 1, ,], f2_(1));
|
||||
assertEquals([0.1, 0.1, 0.1, ,], f2_(0.1));
|
||||
assertEquals([{}, {}, {}, ,], f2_({}));
|
||||
assertEquals([1, 1, 1, ,], f2_(1));
|
||||
|
||||
|
||||
function f3(it) {
|
||||
return [...it, ,];
|
||||
}
|
||||
assertEquals([1, 0.1, "1", , ], f3(g(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1", , ], f3(g({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0, , ], f3(g(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1", , ], f3(g(1, 0.1, "1")));
|
||||
|
||||
function f3_(it) {
|
||||
return [...it, ,];
|
||||
}
|
||||
assertEquals([1, 0.1, "1", , ], f3_(g(1, 0.1, "1")));
|
||||
%OptimizeFunctionOnNextCall(f3_);
|
||||
assertEquals([1, 0.1, "1", , ], f3_(g(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1", , ], f3_(g({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0, , ], f3_(g(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1", , ], f3_(g(1, 0.1, "1")));
|
||||
|
||||
|
||||
function f4(x) {
|
||||
return [...[x, x, x]];
|
||||
}
|
||||
assertEquals([1, 1, 1], f4(1));
|
||||
assertEquals([0.1, 0.1, 0.1], f4(0.1));
|
||||
assertEquals([{}, {}, {}], f4({}));
|
||||
assertEquals([1, 1, 1], f4(1));
|
||||
|
||||
function f4_(x) {
|
||||
return [...[x, x, x]];
|
||||
}
|
||||
assertEquals([1, 1, 1], f4_(1));
|
||||
%OptimizeFunctionOnNextCall(f4_);
|
||||
assertEquals([1, 1, 1], f4_(1));
|
||||
assertEquals([0.1, 0.1, 0.1], f4_(0.1));
|
||||
assertEquals([{}, {}, {}], f4_({}));
|
||||
assertEquals([1, 1, 1], f4_(1));
|
||||
|
||||
|
||||
function f5(x) {
|
||||
return [...[x, x, x], ,];
|
||||
}
|
||||
assertEquals([1, 1, 1, ,], f5(1));
|
||||
assertEquals([0.1, 0.1, 0.1, ,], f5(0.1));
|
||||
assertEquals([{}, {}, {}, ,], f5({}));
|
||||
assertEquals([1, 1, 1, ,], f5(1));
|
||||
|
||||
function f5_(x) {
|
||||
return [...[x, x, x], ,];
|
||||
}
|
||||
assertEquals([1, 1, 1, ,], f5_(1));
|
||||
%OptimizeFunctionOnNextCall(f5_);
|
||||
assertEquals([1, 1, 1, ,], f5_(1));
|
||||
assertEquals([0.1, 0.1, 0.1, ,], f5_(0.1));
|
||||
assertEquals([{}, {}, {}, ,], f5_({}));
|
||||
assertEquals([1, 1, 1, ,], f5_(1));
|
||||
|
||||
|
||||
function f6(it) {
|
||||
return [...it, ,];
|
||||
}
|
||||
assertEquals([1, 0.1, "1", , ], f6(g(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1", , ], f6(g({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0, , ], f6(g(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1", , ], f6(g(1, 0.1, "1")));
|
||||
|
||||
function f6_(it) {
|
||||
return [...it, ,];
|
||||
}
|
||||
assertEquals([1, 0.1, "1", , ], f6_(g(1, 0.1, "1")));
|
||||
%OptimizeFunctionOnNextCall(f6_);
|
||||
assertEquals([1, 0.1, "1", , ], f6_(g(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1", , ], f6_(g({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0, , ], f6_(g(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1", , ], f6_(g(1, 0.1, "1")));
|
||||
|
||||
|
||||
function f7(it) {
|
||||
return [...it];
|
||||
}
|
||||
assertEquals([1, 0.1, "1"], f7(G(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1"], f7(G({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0], f7(G(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1"], f7(G(1, 0.1, "1")));
|
||||
|
||||
function f7_(it) {
|
||||
return [...it];
|
||||
}
|
||||
assertEquals([1, 0.1, "1"], f7_(G(1, 0.1, "1")));
|
||||
%OptimizeFunctionOnNextCall(f7_);
|
||||
assertEquals([1, 0.1, "1"], f7_(G(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1"], f7_(G({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0], f7_(G(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1"], f7_(G(1, 0.1, "1")));
|
||||
|
||||
|
||||
function f8(it) {
|
||||
return [...it, ,];
|
||||
}
|
||||
assertEquals([1, 0.1, "1", , ], f8(G(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1", , ], f8(G({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0, , ], f8(G(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1", , ], f8(G(1, 0.1, "1")));
|
||||
|
||||
function f8_(it) {
|
||||
return [...it, ,];
|
||||
}
|
||||
assertEquals([1, 0.1, "1", , ], f8_(G(1, 0.1, "1")));
|
||||
%OptimizeFunctionOnNextCall(f8_);
|
||||
assertEquals([1, 0.1, "1", , ], f8_(G(1, 0.1, "1")));
|
||||
assertEquals([{}, 0.1, "1", , ], f8_(G({}, 0.1, "1")));
|
||||
assertEquals([0, 0, 0, , ], f8_(G(0, 0, 0)));
|
||||
assertEquals([1, 0.1, "1", , ], f8_(G(1, 0.1, "1")));
|
||||
|
||||
|
||||
// Megamorphic
|
||||
function* f9() {
|
||||
for (let i = 0; i < 160000; ++i) yield i;
|
||||
}
|
||||
let a = [...f9()];
|
||||
assertEquals(160000, a.length);
|
||||
assertEquals(0, a[0]);
|
||||
assertEquals(159999, a[159999]);
|
||||
%OptimizeFunctionOnNextCall(f9);
|
||||
a = [...f9()];
|
||||
assertEquals(160000, a.length);
|
||||
assertEquals(0, a[0]);
|
||||
assertEquals(159999, a[159999]);
|
||||
|
||||
// Slow stub
|
||||
function f10(b) {
|
||||
let x = [
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
...b];
|
||||
return x.length;
|
||||
}
|
||||
assertEquals(4335, f10([3.3, 3.3, 3.3]));
|
||||
assertEquals(4335, f10([{}, "", 3.3]));
|
||||
%OptimizeFunctionOnNextCall(f10);
|
||||
assertEquals(4335, f10([{}, "", 3.3]));
|
||||
assertEquals(4332, f10([]));
|
||||
|
||||
|
||||
} // top-level scope
|
@ -104,6 +104,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
||||
FeedbackSlot strict_keyed_store_slot =
|
||||
feedback_spec.AddKeyedStoreICSlot(LanguageMode::kStrict);
|
||||
FeedbackSlot store_own_slot = feedback_spec.AddStoreOwnICSlot();
|
||||
FeedbackSlot store_array_element_slot =
|
||||
feedback_spec.AddStoreInArrayLiteralICSlot();
|
||||
|
||||
// Emit global load / store operations.
|
||||
const AstRawString* name = ast_factory.GetOneByteString("var_name");
|
||||
@ -141,7 +143,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
||||
LanguageMode::kStrict)
|
||||
.StoreKeyedProperty(reg, reg, strict_keyed_store_slot.ToInt(),
|
||||
LanguageMode::kStrict)
|
||||
.StoreNamedOwnProperty(reg, name, store_own_slot.ToInt());
|
||||
.StoreNamedOwnProperty(reg, name, store_own_slot.ToInt())
|
||||
.StoreInArrayLiteral(reg, reg, store_array_element_slot.ToInt());
|
||||
|
||||
// Emit load / store lookup slots.
|
||||
builder.LoadLookupSlot(name, TypeofMode::NOT_INSIDE_TYPEOF)
|
||||
|
@ -56,6 +56,9 @@ function IcProcessor() {
|
||||
'KeyedStoreIC': {
|
||||
parsers : propertyICParser,
|
||||
processor: this.processPropertyIC.bind(this, "KeyedStoreIC") },
|
||||
'StoreInArrayLiteralIC': {
|
||||
parsers : propertyICParser,
|
||||
processor: this.processPropertyIC.bind(this, "StoreInArrayLiteralIC") },
|
||||
});
|
||||
this.deserializedEntriesNames_ = [];
|
||||
this.profile_ = new Profile();
|
||||
@ -64,6 +67,7 @@ function IcProcessor() {
|
||||
this.StoreIC = 0;
|
||||
this.KeyedLoadIC = 0;
|
||||
this.KeyedStoreIC = 0;
|
||||
this.StoreInArrayLiteralIC = 0;
|
||||
}
|
||||
inherits(IcProcessor, LogReader);
|
||||
|
||||
@ -104,6 +108,7 @@ IcProcessor.prototype.processLogFile = function(fileName) {
|
||||
print("Store: " + this.StoreIC);
|
||||
print("KeyedLoad: " + this.KeyedLoadIC);
|
||||
print("KeyedStore: " + this.KeyedStoreIC);
|
||||
print("StoreInArrayLiteral: " + this.StoreInArrayLiteralIC);
|
||||
};
|
||||
|
||||
IcProcessor.prototype.addEntry = function(entry) {
|
||||
|
Loading…
Reference in New Issue
Block a user