Inline Array.shift() fast path instead of using a code stub.

TEST=mjsunit/array-shift,mjsunit/array-shift2,mjsunit/array-shift3
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/308793010

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21592 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
bmeurer@chromium.org 2014-06-02 07:02:24 +00:00
parent f600133031
commit 7d14f34a1b
29 changed files with 88 additions and 429 deletions

View File

@ -319,16 +319,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
}
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 };

View File

@ -2284,14 +2284,6 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
}
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());

View File

@ -26,7 +26,6 @@ class LCodeGen;
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
@ -2283,21 +2282,6 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 1> {
};
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,

View File

@ -4402,15 +4402,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
}
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());

View File

@ -356,17 +356,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
}
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

View File

@ -2517,14 +2517,6 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
}
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());

View File

@ -28,7 +28,6 @@ class LCodeGen;
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
V(ArrayShift) \
V(BitI) \
V(BitS) \
V(BoundsCheck) \
@ -2888,21 +2887,6 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 2> {
};
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) {

View File

@ -5754,15 +5754,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
}
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());

View File

@ -1120,86 +1120,6 @@ Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
}
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,

View File

@ -16,7 +16,6 @@ namespace internal {
// List of code stubs used on all platforms.
#define CODE_STUB_LIST_ALL_PLATFORMS(V) \
V(ArrayShift) \
V(CallFunction) \
V(CallConstruct) \
V(BinaryOpIC) \
@ -2412,36 +2411,6 @@ class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
};
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)

View File

@ -779,11 +779,9 @@ bool HInstruction::CanDeoptimize() {
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:
@ -849,6 +847,7 @@ bool HInstruction::CanDeoptimize() {
case HValue::kBitwise:
case HValue::kBoundsCheck:
case HValue::kBranch:
case HValue::kCallJSFunction:
case HValue::kCallRuntime:
case HValue::kChange:
case HValue::kCheckHeapObject:
@ -3609,12 +3608,6 @@ void HTransitionElementsKind::PrintDataTo(StringStream* stream) {
}
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)");

View File

@ -51,7 +51,6 @@ class LChunkBuilder;
V(ArgumentsElements) \
V(ArgumentsLength) \
V(ArgumentsObject) \
V(ArrayShift) \
V(Bitwise) \
V(BlockEntry) \
V(BoundsCheck) \
@ -7090,52 +7089,6 @@ class HTransitionElementsKind V8_FINAL : public HTemplateInstruction<2> {
};
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,

View File

@ -7940,13 +7940,96 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
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;
receiver = AddCheckMap(receiver, receiver_map);
HInstruction* result = NewUncasted<HArrayShift>(receiver, kind);
ast_context()->ReturnInstruction(result, expr->id());
{
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);
// 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:

View File

@ -323,16 +323,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
}
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 };

View File

@ -4298,15 +4298,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
}
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:

View File

@ -2319,14 +2319,6 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
}
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());

View File

@ -26,7 +26,6 @@ class LCodeGen;
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
@ -2282,21 +2281,6 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 2> {
};
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,

View File

@ -320,16 +320,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
}
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 };

View File

@ -4404,15 +4404,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
}
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());

View File

@ -2235,14 +2235,6 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
}
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());

View File

@ -26,7 +26,6 @@ class LCodeGen;
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
@ -2238,21 +2237,6 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 1> {
};
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,

View File

@ -319,16 +319,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
}
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 };

View File

@ -4377,15 +4377,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
}
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());

View File

@ -2258,14 +2258,6 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
}
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());

View File

@ -26,7 +26,6 @@ class LCodeGen;
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
@ -2245,21 +2244,6 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 2> {
};
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,

View File

@ -323,16 +323,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
}
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 };

View File

@ -4233,15 +4233,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
}
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:

View File

@ -2309,14 +2309,6 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
}
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());

View File

@ -26,7 +26,6 @@ class LCodeGen;
V(ArgumentsLength) \
V(ArithmeticD) \
V(ArithmeticT) \
V(ArrayShift) \
V(BitI) \
V(BoundsCheck) \
V(Branch) \
@ -2292,21 +2291,6 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 2> {
};
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,