}
-void ArrayShiftStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- static Register registers[] = { r0 };
- descriptor->register_param_count_ = 1;
- descriptor->register_params_ = registers;
- descriptor->deoptimization_handler_ =
- Builtins::c_function_address(Builtins::c_ArrayShift);
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
}
-LInstruction* LChunkBuilder::DoArrayShift(HArrayShift* instr) {
- LOperand* object = UseFixed(instr->object(), r0);
- LOperand* context = UseFixed(instr->context(), cp);
- LArrayShift* result = new(zone()) LArrayShift(context, object);
- return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
-}
-
-
LInstruction* LChunkBuilder::DoTrapAllocationMemento(
HTrapAllocationMemento* instr) {
LOperand* object = UseRegister(instr->object());
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
};
-class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LArrayShift(LOperand* context, LOperand* object) {
- inputs_[0] = context;
- inputs_[1] = object;
- }
-
- LOperand* context() const { return inputs_[0]; }
- LOperand* object() const { return inputs_[1]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
- DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
-};
-
-
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
LTrapAllocationMemento(LOperand* object,
}
-void LCodeGen::DoArrayShift(LArrayShift* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(r0));
- ASSERT(ToRegister(instr->result()).is(r0));
- ArrayShiftStub stub(isolate(), instr->hydrogen()->kind());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
Register object = ToRegister(instr->object());
Register temp = ToRegister(instr->temp());
}
-void ArrayShiftStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // x0: receiver
- static Register registers[] = { x0 };
- descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
- descriptor->register_params_ = registers;
- descriptor->deoptimization_handler_ =
- Builtins::c_function_address(Builtins::c_ArrayShift);
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: left operand
}
-LInstruction* LChunkBuilder::DoArrayShift(HArrayShift* instr) {
- LOperand* object = UseFixed(instr->object(), x0);
- LOperand* context = UseFixed(instr->context(), cp);
- LArrayShift* result = new(zone()) LArrayShift(context, object);
- return MarkAsCall(DefineFixed(result, x0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
-}
-
-
LInstruction* LChunkBuilder::DoTrapAllocationMemento(
HTrapAllocationMemento* instr) {
LOperand* object = UseRegister(instr->object());
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayShift) \
V(BitI) \
V(BitS) \
V(BoundsCheck) \
};
-class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LArrayShift(LOperand* context, LOperand* object) {
- inputs_[0] = context;
- inputs_[1] = object;
- }
-
- LOperand* context() const { return inputs_[0]; }
- LOperand* object() const { return inputs_[1]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
- DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
-};
-
-
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 2> {
public:
LTrapAllocationMemento(LOperand* object, LOperand* temp1, LOperand* temp2) {
}
-void LCodeGen::DoArrayShift(LArrayShift* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(x0));
- ASSERT(ToRegister(instr->result()).is(x0));
- ArrayShiftStub stub(isolate(), instr->hydrogen()->kind());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
Register object = ToRegister(instr->object());
Register temp1 = ToRegister(instr->temp1());
}
-template <>
-HValue* CodeStubGraphBuilder<ArrayShiftStub>::BuildCodeStub() {
- HValue* receiver = GetParameter(ArrayShiftStub::kReceiver);
- ElementsKind kind = casted_stub()->kind();
-
- // We may use double registers for copying.
- if (IsFastDoubleElementsKind(kind)) info()->MarkAsSavesCallerDoubles();
-
- HValue* length = Add<HLoadNamedField>(
- receiver, static_cast<HValue*>(NULL),
- HObjectAccess::ForArrayLength(kind));
-
- IfBuilder if_lengthiszero(this);
- HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>(
- length, graph()->GetConstant0(), Token::EQ);
- if_lengthiszero.Then();
- {
- Push(graph()->GetConstantUndefined());
- }
- if_lengthiszero.Else();
- {
- // Check if array length is below threshold.
- IfBuilder if_inline(this);
- if_inline.If<HCompareNumericAndBranch>(
- length, Add<HConstant>(ArrayShiftStub::kInlineThreshold), Token::LTE);
- if_inline.Then();
- if_inline.ElseDeopt("Array length exceeds threshold");
- if_inline.End();
-
- // We cannot handle copy-on-write backing stores here.
- HValue* elements = AddLoadElements(receiver);
- if (IsFastSmiOrObjectElementsKind(kind)) {
- Add<HCheckMaps>(elements, isolate()->factory()->fixed_array_map());
- }
-
- // Remember the result.
- Push(AddElementAccess(elements, graph()->GetConstant0(), NULL,
- lengthiszero, kind, LOAD));
-
- // Compute the new length.
- HValue* new_length = AddUncasted<HSub>(length, graph()->GetConstant1());
- new_length->ClearFlag(HValue::kCanOverflow);
-
- // Copy the remaining elements.
- LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
- {
- HValue* new_key = loop.BeginBody(
- graph()->GetConstant0(), new_length, Token::LT);
- HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1());
- key->ClearFlag(HValue::kCanOverflow);
- HValue* element = AddUncasted<HLoadKeyed>(
- elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE);
- HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element, kind);
- store->SetFlag(HValue::kAllowUndefinedAsNaN);
- }
- loop.EndBody();
-
- // Put a hole at the end.
- HValue* hole = IsFastSmiOrObjectElementsKind(kind)
- ? Add<HConstant>(isolate()->factory()->the_hole_value())
- : Add<HConstant>(FixedDoubleArray::hole_nan_as_double());
- if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS;
- Add<HStoreKeyed>(elements, new_length, hole, kind, INITIALIZING_STORE);
-
- // Remember new length.
- Add<HStoreNamedField>(
- receiver, HObjectAccess::ForArrayLength(kind),
- new_length, STORE_TO_INITIALIZED_ENTRY);
- }
- if_lengthiszero.End();
-
- return Pop();
-}
-
-
-Handle<Code> ArrayShiftStub::GenerateCode() {
- return DoGenerateCode(this);
-}
-
-
void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
HValue* js_function,
HValue* native_context,
// List of code stubs used on all platforms.
#define CODE_STUB_LIST_ALL_PLATFORMS(V) \
- V(ArrayShift) \
V(CallFunction) \
V(CallConstruct) \
V(BinaryOpIC) \
};
-class ArrayShiftStub V8_FINAL : public HydrogenCodeStub {
- public:
- ArrayShiftStub(Isolate* isolate, ElementsKind kind)
- : HydrogenCodeStub(isolate), kind_(kind) { }
-
- ElementsKind kind() const { return kind_; }
-
- virtual Handle<Code> GenerateCode() V8_OVERRIDE;
-
- virtual void InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
-
- // Inline Array.shift() for arrays up to this length.
- static const int kInlineThreshold = 16;
-
- // Parameters accessed via CodeStubGraphBuilder::GetParameter()
- static const int kReceiver = 0;
-
- private:
- Major MajorKey() { return ArrayShift; }
- int NotMissMinorKey() {
- return kind_;
- }
-
- ElementsKind kind_;
-
- DISALLOW_COPY_AND_ASSIGN(ArrayShiftStub);
-};
-
-
class StoreArrayLiteralElementStub : public PlatformCodeStub {
public:
explicit StoreArrayLiteralElementStub(Isolate* isolate)
case HValue::kArgumentsElements:
case HValue::kArgumentsLength:
case HValue::kArgumentsObject:
- case HValue::kArrayShift:
case HValue::kBlockEntry:
case HValue::kBoundsCheckBaseIndexInformation:
case HValue::kCallFunction:
- case HValue::kCallJSFunction:
case HValue::kCallNew:
case HValue::kCallNewArray:
case HValue::kCallStub:
case HValue::kBitwise:
case HValue::kBoundsCheck:
case HValue::kBranch:
+ case HValue::kCallJSFunction:
case HValue::kCallRuntime:
case HValue::kChange:
case HValue::kCheckHeapObject:
}
-void HArrayShift::PrintDataTo(StringStream* stream) {
- object()->PrintNameTo(stream);
- stream->Add(" [%s]", ElementsAccessor::ForKind(kind())->name());
-}
-
-
void HLoadGlobalCell::PrintDataTo(StringStream* stream) {
stream->Add("[%p]", *cell().handle());
if (!details_.IsDontDelete()) stream->Add(" (deleteable)");
V(ArgumentsElements) \
V(ArgumentsLength) \
V(ArgumentsObject) \
- V(ArrayShift) \
V(Bitwise) \
V(BlockEntry) \
V(BoundsCheck) \
};
-class HArrayShift V8_FINAL : public HTemplateInstruction<2> {
- public:
- static HArrayShift* New(Zone* zone,
- HValue* context,
- HValue* object,
- ElementsKind kind) {
- return new(zone) HArrayShift(context, object, kind);
- }
-
- virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
- return Representation::Tagged();
- }
-
- HValue* context() const { return OperandAt(0); }
- HValue* object() const { return OperandAt(1); }
- ElementsKind kind() const { return kind_; }
-
- virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift);
-
- protected:
- virtual bool DataEquals(HValue* other) V8_OVERRIDE {
- HArrayShift* that = HArrayShift::cast(other);
- return this->kind_ == that->kind_;
- }
-
- private:
- HArrayShift(HValue* context, HValue* object, ElementsKind kind)
- : kind_(kind) {
- SetOperandAt(0, context);
- SetOperandAt(1, object);
- SetChangesFlag(kArrayLengths);
- SetChangesFlag(kNewSpacePromotion);
- set_representation(Representation::Tagged());
- if (IsFastSmiOrObjectElementsKind(kind)) {
- SetChangesFlag(kArrayElements);
- } else {
- SetChangesFlag(kDoubleArrayElements);
- }
- }
-
- ElementsKind kind_;
-};
-
-
class HStringAdd V8_FINAL : public HBinaryOperation {
public:
static HInstruction* New(Zone* zone,
handle(JSObject::cast(receiver_map->prototype()), isolate()),
Handle<JSObject>::null());
+ // Threshold for fast inlined Array.shift().
+ HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16));
+
Drop(expr->arguments()->length());
HValue* receiver = Pop();
- Drop(1); // function
+ HValue* function = Pop();
+ HValue* result;
+
+ {
+ NoObservableSideEffectsScope scope(this);
+
+ HValue* length = Add<HLoadNamedField>(
+ receiver, static_cast<HValue*>(NULL),
+ HObjectAccess::ForArrayLength(kind));
+
+ IfBuilder if_lengthiszero(this);
+ HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>(
+ length, graph()->GetConstant0(), Token::EQ);
+ if_lengthiszero.Then();
+ {
+ if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined());
+ }
+ if_lengthiszero.Else();
+ {
+ HValue* elements = AddLoadElements(receiver);
+
+ // Check if we can use the fast inlined Array.shift().
+ IfBuilder if_inline(this);
+ if_inline.If<HCompareNumericAndBranch>(
+ length, inline_threshold, Token::LTE);
+ if (IsFastSmiOrObjectElementsKind(kind)) {
+ // We cannot handle copy-on-write backing stores here.
+ if_inline.AndIf<HCompareMap>(
+ elements, isolate()->factory()->fixed_array_map());
+ }
+ if_inline.Then();
+ {
+ // Remember the result.
+ if (!ast_context()->IsEffect()) {
+ Push(AddElementAccess(elements, graph()->GetConstant0(), NULL,
+ lengthiszero, kind, LOAD));
+ }
+
+ // Compute the new length.
+ HValue* new_length = AddUncasted<HSub>(
+ length, graph()->GetConstant1());
+ new_length->ClearFlag(HValue::kCanOverflow);
- receiver = AddCheckMap(receiver, receiver_map);
- HInstruction* result = NewUncasted<HArrayShift>(receiver, kind);
- ast_context()->ReturnInstruction(result, expr->id());
+ // Copy the remaining elements.
+ LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
+ {
+ HValue* new_key = loop.BeginBody(
+ graph()->GetConstant0(), new_length, Token::LT);
+ HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1());
+ key->ClearFlag(HValue::kCanOverflow);
+ HValue* element = AddUncasted<HLoadKeyed>(
+ elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE);
+ HStoreKeyed* store = Add<HStoreKeyed>(
+ elements, new_key, element, kind);
+ store->SetFlag(HValue::kAllowUndefinedAsNaN);
+ }
+ loop.EndBody();
+
+ // Put a hole at the end.
+ HValue* hole = IsFastSmiOrObjectElementsKind(kind)
+ ? Add<HConstant>(isolate()->factory()->the_hole_value())
+ : Add<HConstant>(FixedDoubleArray::hole_nan_as_double());
+ if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS;
+ Add<HStoreKeyed>(
+ elements, new_length, hole, kind, INITIALIZING_STORE);
+
+ // Remember new length.
+ Add<HStoreNamedField>(
+ receiver, HObjectAccess::ForArrayLength(kind),
+ new_length, STORE_TO_INITIALIZED_ENTRY);
+ }
+ if_inline.Else();
+ {
+ Add<HPushArguments>(receiver);
+ result = Add<HCallJSFunction>(function, 1, true);
+ if (!ast_context()->IsEffect()) Push(result);
+ }
+ if_inline.End();
+ }
+ if_lengthiszero.End();
+ }
+ result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
+ Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
+ if (!ast_context()->IsEffect()) Drop(1);
+ ast_context()->ReturnValue(result);
return true;
}
default:
}
-void ArrayShiftStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- static Register registers[] = { eax };
- descriptor->register_param_count_ = 1;
- descriptor->register_params_ = registers;
- descriptor->deoptimization_handler_ =
- Builtins::c_function_address(Builtins::c_ArrayShift);
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, eax };
}
-void LCodeGen::DoArrayShift(LArrayShift* instr) {
- ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->object()).is(eax));
- ASSERT(ToRegister(instr->result()).is(eax));
- ArrayShiftStub stub(isolate(), instr->hydrogen()->kind());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
public:
}
-LInstruction* LChunkBuilder::DoArrayShift(HArrayShift* instr) {
- LOperand* object = UseFixed(instr->object(), eax);
- LOperand* context = UseFixed(instr->context(), esi);
- LArrayShift* result = new(zone()) LArrayShift(context, object);
- return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
-}
-
-
LInstruction* LChunkBuilder::DoTrapAllocationMemento(
HTrapAllocationMemento* instr) {
LOperand* object = UseRegister(instr->object());
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
};
-class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LArrayShift(LOperand* context, LOperand* object) {
- inputs_[0] = context;
- inputs_[1] = object;
- }
-
- LOperand* context() const { return inputs_[0]; }
- LOperand* object() const { return inputs_[1]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
- DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
-};
-
-
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
LTrapAllocationMemento(LOperand* object,
}
-void ArrayShiftStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- static Register registers[] = { a0 };
- descriptor->register_param_count_ = 1;
- descriptor->register_params_ = registers;
- descriptor->deoptimization_handler_ =
- Builtins::c_function_address(Builtins::c_ArrayShift);
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
}
-void LCodeGen::DoArrayShift(LArrayShift* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(a0));
- ASSERT(ToRegister(instr->result()).is(v0));
- ArrayShiftStub stub(isolate(), instr->hydrogen()->kind());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
Register object = ToRegister(instr->object());
Register temp = ToRegister(instr->temp());
}
-LInstruction* LChunkBuilder::DoArrayShift(HArrayShift* instr) {
- LOperand* object = UseFixed(instr->object(), a0);
- LOperand* context = UseFixed(instr->context(), cp);
- LArrayShift* result = new(zone()) LArrayShift(context, object);
- return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
-}
-
-
LInstruction* LChunkBuilder::DoTrapAllocationMemento(
HTrapAllocationMemento* instr) {
LOperand* object = UseRegister(instr->object());
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
};
-class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LArrayShift(LOperand* context, LOperand* object) {
- inputs_[0] = context;
- inputs_[1] = object;
- }
-
- LOperand* context() const { return inputs_[0]; }
- LOperand* object() const { return inputs_[1]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
- DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
-};
-
-
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
LTrapAllocationMemento(LOperand* object,
}
-void ArrayShiftStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- static Register registers[] = { rax };
- descriptor->register_param_count_ = 1;
- descriptor->register_params_ = registers;
- descriptor->deoptimization_handler_ =
- Builtins::c_function_address(Builtins::c_ArrayShift);
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
}
-void LCodeGen::DoArrayShift(LArrayShift* instr) {
- ASSERT(ToRegister(instr->context()).is(rsi));
- ASSERT(ToRegister(instr->object()).is(rax));
- ASSERT(ToRegister(instr->result()).is(rax));
- ArrayShiftStub stub(isolate(), instr->hydrogen()->kind());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
Register object = ToRegister(instr->object());
Register temp = ToRegister(instr->temp());
}
-LInstruction* LChunkBuilder::DoArrayShift(HArrayShift* instr) {
- LOperand* object = UseFixed(instr->object(), rax);
- LOperand* context = UseFixed(instr->context(), rsi);
- LArrayShift* result = new(zone()) LArrayShift(context, object);
- return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
-}
-
-
LInstruction* LChunkBuilder::DoTrapAllocationMemento(
HTrapAllocationMemento* instr) {
LOperand* object = UseRegister(instr->object());
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
};
-class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LArrayShift(LOperand* context, LOperand* object) {
- inputs_[0] = context;
- inputs_[1] = object;
- }
-
- LOperand* context() const { return inputs_[0]; }
- LOperand* object() const { return inputs_[1]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
- DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
-};
-
-
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
LTrapAllocationMemento(LOperand* object,
}
-void ArrayShiftStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- static Register registers[] = { eax };
- descriptor->register_param_count_ = 1;
- descriptor->register_params_ = registers;
- descriptor->deoptimization_handler_ =
- Builtins::c_function_address(Builtins::c_ArrayShift);
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, eax };
}
-void LCodeGen::DoArrayShift(LArrayShift* instr) {
- ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->object()).is(eax));
- ASSERT(ToRegister(instr->result()).is(eax));
- ArrayShiftStub stub(isolate(), instr->hydrogen()->kind());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
public:
}
-LInstruction* LChunkBuilder::DoArrayShift(HArrayShift* instr) {
- LOperand* object = UseFixed(instr->object(), eax);
- LOperand* context = UseFixed(instr->context(), esi);
- LArrayShift* result = new(zone()) LArrayShift(context, object);
- return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
-}
-
-
LInstruction* LChunkBuilder::DoTrapAllocationMemento(
HTrapAllocationMemento* instr) {
LOperand* object = UseRegister(instr->object());
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
- V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
};
-class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
- public:
- LArrayShift(LOperand* context, LOperand* object) {
- inputs_[0] = context;
- inputs_[1] = object;
- }
-
- LOperand* context() const { return inputs_[0]; }
- LOperand* object() const { return inputs_[1]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
- DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
-};
-
-
class LTrapAllocationMemento V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
LTrapAllocationMemento(LOperand* object,