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:
parent
f600133031
commit
7d14f34a1b
@ -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 };
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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)");
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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 };
|
||||
|
@ -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:
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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 };
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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 };
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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 };
|
||||
|
@ -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:
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user