[turbofan] JSGenericLowering mostly uses builtins instead of code stubs now
BUG=v8:5431 Review-Url: https://codereview.chromium.org/2372113004 Cr-Commit-Position: refs/heads/master@{#40051}
This commit is contained in:
parent
e97ca6ec47
commit
0c168a90ff
@ -2443,8 +2443,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(r0, r1);
|
||||
__ mov(r0, r3);
|
||||
__ Push(cp);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(cp);
|
||||
__ mov(r3, r0);
|
||||
__ Pop(r0, r1);
|
||||
|
@ -2512,8 +2512,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(x0, x1);
|
||||
__ Mov(x0, x3);
|
||||
__ Push(cp);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(cp);
|
||||
__ Mov(x3, x0);
|
||||
__ Pop(x1, x0);
|
||||
|
@ -319,5 +319,168 @@ void Builtins::Generate_ToBoolean(CodeStubAssembler* assembler) {
|
||||
assembler->Return(assembler->BooleanConstant(false));
|
||||
}
|
||||
|
||||
void Builtins::Generate_ToLength(CodeStubAssembler* assembler) {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
Node* context = assembler->Parameter(1);
|
||||
|
||||
// We might need to loop once for ToNumber conversion.
|
||||
Variable var_len(assembler, MachineRepresentation::kTagged);
|
||||
Label loop(assembler, &var_len);
|
||||
var_len.Bind(assembler->Parameter(0));
|
||||
assembler->Goto(&loop);
|
||||
assembler->Bind(&loop);
|
||||
{
|
||||
// Shared entry points.
|
||||
Label return_len(assembler),
|
||||
return_two53minus1(assembler, Label::kDeferred),
|
||||
return_zero(assembler, Label::kDeferred);
|
||||
|
||||
// Load the current {len} value.
|
||||
Node* len = var_len.value();
|
||||
|
||||
// Check if {len} is a positive Smi.
|
||||
assembler->GotoIf(assembler->WordIsPositiveSmi(len), &return_len);
|
||||
|
||||
// Check if {len} is a (negative) Smi.
|
||||
assembler->GotoIf(assembler->WordIsSmi(len), &return_zero);
|
||||
|
||||
// Check if {len} is a HeapNumber.
|
||||
Label if_lenisheapnumber(assembler),
|
||||
if_lenisnotheapnumber(assembler, Label::kDeferred);
|
||||
assembler->Branch(assembler->IsHeapNumberMap(assembler->LoadMap(len)),
|
||||
&if_lenisheapnumber, &if_lenisnotheapnumber);
|
||||
|
||||
assembler->Bind(&if_lenisheapnumber);
|
||||
{
|
||||
// Load the floating-point value of {len}.
|
||||
Node* len_value = assembler->LoadHeapNumberValue(len);
|
||||
|
||||
// Check if {len} is not greater than zero.
|
||||
assembler->GotoUnless(assembler->Float64GreaterThan(
|
||||
len_value, assembler->Float64Constant(0.0)),
|
||||
&return_zero);
|
||||
|
||||
// Check if {len} is greater than or equal to 2^53-1.
|
||||
assembler->GotoIf(
|
||||
assembler->Float64GreaterThanOrEqual(
|
||||
len_value, assembler->Float64Constant(kMaxSafeInteger)),
|
||||
&return_two53minus1);
|
||||
|
||||
// Round the {len} towards -Infinity.
|
||||
Node* value = assembler->Float64Floor(len_value);
|
||||
Node* result = assembler->ChangeFloat64ToTagged(value);
|
||||
assembler->Return(result);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_lenisnotheapnumber);
|
||||
{
|
||||
// Need to convert {len} to a Number first.
|
||||
Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate());
|
||||
var_len.Bind(assembler->CallStub(callable, context, len));
|
||||
assembler->Goto(&loop);
|
||||
}
|
||||
|
||||
assembler->Bind(&return_len);
|
||||
assembler->Return(var_len.value());
|
||||
|
||||
assembler->Bind(&return_two53minus1);
|
||||
assembler->Return(assembler->NumberConstant(kMaxSafeInteger));
|
||||
|
||||
assembler->Bind(&return_zero);
|
||||
assembler->Return(assembler->SmiConstant(Smi::FromInt(0)));
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_ToInteger(CodeStubAssembler* assembler) {
|
||||
typedef TypeConversionDescriptor Descriptor;
|
||||
|
||||
compiler::Node* input = assembler->Parameter(Descriptor::kArgument);
|
||||
compiler::Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
assembler->Return(assembler->ToInteger(context, input));
|
||||
}
|
||||
|
||||
// ES6 section 7.1.13 ToObject (argument)
|
||||
void Builtins::Generate_ToObject(CodeStubAssembler* assembler) {
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
typedef TypeConversionDescriptor Descriptor;
|
||||
|
||||
Label if_number(assembler, Label::kDeferred), if_notsmi(assembler),
|
||||
if_jsreceiver(assembler), if_noconstructor(assembler, Label::kDeferred),
|
||||
if_wrapjsvalue(assembler);
|
||||
|
||||
Node* object = assembler->Parameter(Descriptor::kArgument);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
Variable constructor_function_index_var(assembler,
|
||||
MachineType::PointerRepresentation());
|
||||
|
||||
assembler->Branch(assembler->WordIsSmi(object), &if_number, &if_notsmi);
|
||||
|
||||
assembler->Bind(&if_notsmi);
|
||||
Node* map = assembler->LoadMap(object);
|
||||
|
||||
assembler->GotoIf(assembler->IsHeapNumberMap(map), &if_number);
|
||||
|
||||
Node* instance_type = assembler->LoadMapInstanceType(map);
|
||||
assembler->GotoIf(assembler->IsJSReceiverInstanceType(instance_type),
|
||||
&if_jsreceiver);
|
||||
|
||||
Node* constructor_function_index =
|
||||
assembler->LoadMapConstructorFunctionIndex(map);
|
||||
assembler->GotoIf(assembler->WordEqual(constructor_function_index,
|
||||
assembler->IntPtrConstant(
|
||||
Map::kNoConstructorFunctionIndex)),
|
||||
&if_noconstructor);
|
||||
constructor_function_index_var.Bind(constructor_function_index);
|
||||
assembler->Goto(&if_wrapjsvalue);
|
||||
|
||||
assembler->Bind(&if_number);
|
||||
constructor_function_index_var.Bind(
|
||||
assembler->IntPtrConstant(Context::NUMBER_FUNCTION_INDEX));
|
||||
assembler->Goto(&if_wrapjsvalue);
|
||||
|
||||
assembler->Bind(&if_wrapjsvalue);
|
||||
Node* native_context = assembler->LoadNativeContext(context);
|
||||
Node* constructor = assembler->LoadFixedArrayElement(
|
||||
native_context, constructor_function_index_var.value(), 0,
|
||||
CodeStubAssembler::INTPTR_PARAMETERS);
|
||||
Node* initial_map = assembler->LoadObjectField(
|
||||
constructor, JSFunction::kPrototypeOrInitialMapOffset);
|
||||
Node* js_value = assembler->Allocate(JSValue::kSize);
|
||||
assembler->StoreMapNoWriteBarrier(js_value, initial_map);
|
||||
assembler->StoreObjectFieldRoot(js_value, JSValue::kPropertiesOffset,
|
||||
Heap::kEmptyFixedArrayRootIndex);
|
||||
assembler->StoreObjectFieldRoot(js_value, JSObject::kElementsOffset,
|
||||
Heap::kEmptyFixedArrayRootIndex);
|
||||
assembler->StoreObjectField(js_value, JSValue::kValueOffset, object);
|
||||
assembler->Return(js_value);
|
||||
|
||||
assembler->Bind(&if_noconstructor);
|
||||
assembler->TailCallRuntime(
|
||||
Runtime::kThrowUndefinedOrNullToObject, context,
|
||||
assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
|
||||
"ToObject", TENURED)));
|
||||
|
||||
assembler->Bind(&if_jsreceiver);
|
||||
assembler->Return(object);
|
||||
}
|
||||
|
||||
// ES6 section 12.5.5 typeof operator
|
||||
void Builtins::Generate_Typeof(CodeStubAssembler* assembler) {
|
||||
typedef compiler::Node Node;
|
||||
typedef TypeofDescriptor Descriptor;
|
||||
|
||||
Node* object = assembler->Parameter(Descriptor::kObject);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
assembler->Return(assembler->Typeof(object, context));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -906,5 +906,38 @@ BUILTIN(ObjectSeal) {
|
||||
return *object;
|
||||
}
|
||||
|
||||
void Builtins::Generate_HasProperty(CodeStubAssembler* assembler) {
|
||||
typedef HasPropertyDescriptor Descriptor;
|
||||
typedef compiler::Node Node;
|
||||
|
||||
Node* key = assembler->Parameter(Descriptor::kKey);
|
||||
Node* object = assembler->Parameter(Descriptor::kObject);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
assembler->Return(
|
||||
assembler->HasProperty(object, key, context, Runtime::kHasProperty));
|
||||
}
|
||||
|
||||
void Builtins::Generate_ForInFilter(CodeStubAssembler* assembler) {
|
||||
typedef compiler::Node Node;
|
||||
typedef ForInFilterDescriptor Descriptor;
|
||||
|
||||
Node* key = assembler->Parameter(Descriptor::kKey);
|
||||
Node* object = assembler->Parameter(Descriptor::kObject);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
assembler->Return(assembler->ForInFilter(key, object, context));
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstanceOf(CodeStubAssembler* assembler) {
|
||||
typedef compiler::Node Node;
|
||||
typedef CompareDescriptor Descriptor;
|
||||
Node* object = assembler->Parameter(Descriptor::kLeft);
|
||||
Node* callable = assembler->Parameter(Descriptor::kRight);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
assembler->Return(assembler->InstanceOf(object, callable, context));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -10,9 +10,10 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
typedef CodeStubAssembler::ResultMode ResultMode;
|
||||
typedef CodeStubAssembler::RelationalComparisonMode RelationalComparisonMode;
|
||||
|
||||
enum ResultMode { kDontNegateResult, kNegateResult };
|
||||
namespace {
|
||||
|
||||
void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) {
|
||||
// Here's pseudo-code for the algorithm below in case of kDontNegateResult
|
||||
@ -168,9 +169,10 @@ void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) {
|
||||
{
|
||||
// TODO(bmeurer): Add fast case support for flattened cons strings;
|
||||
// also add support for two byte string equality checks.
|
||||
Runtime::FunctionId function_id = (mode == kDontNegateResult)
|
||||
? Runtime::kStringEqual
|
||||
: Runtime::kStringNotEqual;
|
||||
Runtime::FunctionId function_id =
|
||||
(mode == ResultMode::kDontNegateResult)
|
||||
? Runtime::kStringEqual
|
||||
: Runtime::kStringNotEqual;
|
||||
assembler->TailCallRuntime(function_id, context, lhs, rhs);
|
||||
}
|
||||
}
|
||||
@ -184,18 +186,14 @@ void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) {
|
||||
}
|
||||
|
||||
assembler->Bind(&if_equal);
|
||||
assembler->Return(assembler->BooleanConstant(mode == kDontNegateResult));
|
||||
assembler->Return(
|
||||
assembler->BooleanConstant(mode == ResultMode::kDontNegateResult));
|
||||
|
||||
assembler->Bind(&if_notequal);
|
||||
assembler->Return(assembler->BooleanConstant(mode == kNegateResult));
|
||||
assembler->Return(
|
||||
assembler->BooleanConstant(mode == ResultMode::kNegateResult));
|
||||
}
|
||||
|
||||
enum RelationalComparisonMode {
|
||||
kLessThan,
|
||||
kLessThanOrEqual,
|
||||
kGreaterThan,
|
||||
kGreaterThanOrEqual
|
||||
};
|
||||
|
||||
void GenerateStringRelationalComparison(CodeStubAssembler* assembler,
|
||||
RelationalComparisonMode mode) {
|
||||
@ -320,19 +318,19 @@ void GenerateStringRelationalComparison(CodeStubAssembler* assembler,
|
||||
// TODO(bmeurer): Add fast case support for flattened cons strings;
|
||||
// also add support for two byte string relational comparisons.
|
||||
switch (mode) {
|
||||
case kLessThan:
|
||||
case RelationalComparisonMode::kLessThan:
|
||||
assembler->TailCallRuntime(Runtime::kStringLessThan, context, lhs,
|
||||
rhs);
|
||||
break;
|
||||
case kLessThanOrEqual:
|
||||
case RelationalComparisonMode::kLessThanOrEqual:
|
||||
assembler->TailCallRuntime(Runtime::kStringLessThanOrEqual, context,
|
||||
lhs, rhs);
|
||||
break;
|
||||
case kGreaterThan:
|
||||
case RelationalComparisonMode::kGreaterThan:
|
||||
assembler->TailCallRuntime(Runtime::kStringGreaterThan, context, lhs,
|
||||
rhs);
|
||||
break;
|
||||
case kGreaterThanOrEqual:
|
||||
case RelationalComparisonMode::kGreaterThanOrEqual:
|
||||
assembler->TailCallRuntime(Runtime::kStringGreaterThanOrEqual,
|
||||
context, lhs, rhs);
|
||||
break;
|
||||
@ -342,39 +340,39 @@ void GenerateStringRelationalComparison(CodeStubAssembler* assembler,
|
||||
|
||||
assembler->Bind(&if_less);
|
||||
switch (mode) {
|
||||
case kLessThan:
|
||||
case kLessThanOrEqual:
|
||||
case RelationalComparisonMode::kLessThan:
|
||||
case RelationalComparisonMode::kLessThanOrEqual:
|
||||
assembler->Return(assembler->BooleanConstant(true));
|
||||
break;
|
||||
|
||||
case kGreaterThan:
|
||||
case kGreaterThanOrEqual:
|
||||
case RelationalComparisonMode::kGreaterThan:
|
||||
case RelationalComparisonMode::kGreaterThanOrEqual:
|
||||
assembler->Return(assembler->BooleanConstant(false));
|
||||
break;
|
||||
}
|
||||
|
||||
assembler->Bind(&if_equal);
|
||||
switch (mode) {
|
||||
case kLessThan:
|
||||
case kGreaterThan:
|
||||
case RelationalComparisonMode::kLessThan:
|
||||
case RelationalComparisonMode::kGreaterThan:
|
||||
assembler->Return(assembler->BooleanConstant(false));
|
||||
break;
|
||||
|
||||
case kLessThanOrEqual:
|
||||
case kGreaterThanOrEqual:
|
||||
case RelationalComparisonMode::kLessThanOrEqual:
|
||||
case RelationalComparisonMode::kGreaterThanOrEqual:
|
||||
assembler->Return(assembler->BooleanConstant(true));
|
||||
break;
|
||||
}
|
||||
|
||||
assembler->Bind(&if_greater);
|
||||
switch (mode) {
|
||||
case kLessThan:
|
||||
case kLessThanOrEqual:
|
||||
case RelationalComparisonMode::kLessThan:
|
||||
case RelationalComparisonMode::kLessThanOrEqual:
|
||||
assembler->Return(assembler->BooleanConstant(false));
|
||||
break;
|
||||
|
||||
case kGreaterThan:
|
||||
case kGreaterThanOrEqual:
|
||||
case RelationalComparisonMode::kGreaterThan:
|
||||
case RelationalComparisonMode::kGreaterThanOrEqual:
|
||||
assembler->Return(assembler->BooleanConstant(true));
|
||||
break;
|
||||
}
|
||||
@ -384,32 +382,36 @@ void GenerateStringRelationalComparison(CodeStubAssembler* assembler,
|
||||
|
||||
// static
|
||||
void Builtins::Generate_StringEqual(CodeStubAssembler* assembler) {
|
||||
GenerateStringEqual(assembler, kDontNegateResult);
|
||||
GenerateStringEqual(assembler, ResultMode::kDontNegateResult);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_StringNotEqual(CodeStubAssembler* assembler) {
|
||||
GenerateStringEqual(assembler, kNegateResult);
|
||||
GenerateStringEqual(assembler, ResultMode::kNegateResult);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_StringLessThan(CodeStubAssembler* assembler) {
|
||||
GenerateStringRelationalComparison(assembler, kLessThan);
|
||||
GenerateStringRelationalComparison(assembler,
|
||||
RelationalComparisonMode::kLessThan);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_StringLessThanOrEqual(CodeStubAssembler* assembler) {
|
||||
GenerateStringRelationalComparison(assembler, kLessThanOrEqual);
|
||||
GenerateStringRelationalComparison(
|
||||
assembler, RelationalComparisonMode::kLessThanOrEqual);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_StringGreaterThan(CodeStubAssembler* assembler) {
|
||||
GenerateStringRelationalComparison(assembler, kGreaterThan);
|
||||
GenerateStringRelationalComparison(assembler,
|
||||
RelationalComparisonMode::kGreaterThan);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_StringGreaterThanOrEqual(CodeStubAssembler* assembler) {
|
||||
GenerateStringRelationalComparison(assembler, kGreaterThanOrEqual);
|
||||
GenerateStringRelationalComparison(
|
||||
assembler, RelationalComparisonMode::kGreaterThanOrEqual);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -52,6 +52,8 @@ namespace internal {
|
||||
/* Code aging */ \
|
||||
CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, ASM) \
|
||||
\
|
||||
TFS(ToObject, BUILTIN, kNoExtraICState, TypeConversion) \
|
||||
\
|
||||
/* Calls */ \
|
||||
ASM(ArgumentsAdaptorTrampoline) \
|
||||
/* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \
|
||||
@ -172,6 +174,9 @@ namespace internal {
|
||||
TFS(NonNumberToNumber, BUILTIN, kNoExtraICState, TypeConversion) \
|
||||
TFS(ToNumber, BUILTIN, kNoExtraICState, TypeConversion) \
|
||||
TFS(ToString, BUILTIN, kNoExtraICState, TypeConversion) \
|
||||
TFS(ToInteger, BUILTIN, kNoExtraICState, TypeConversion) \
|
||||
TFS(ToLength, BUILTIN, kNoExtraICState, TypeConversion) \
|
||||
TFS(Typeof, BUILTIN, kNoExtraICState, Typeof) \
|
||||
\
|
||||
/* Handlers */ \
|
||||
ASH(KeyedLoadIC_Megamorphic, KEYED_LOAD_IC, kNoExtraICState) \
|
||||
@ -482,6 +487,25 @@ namespace internal {
|
||||
CPP(NumberPrototypeToString) \
|
||||
/* ES6 section 20.1.3.7 Number.prototype.valueOf ( ) */ \
|
||||
TFJ(NumberPrototypeValueOf, 1) \
|
||||
TFS(Add, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(Subtract, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(Multiply, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(Divide, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(Modulus, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(BitwiseAnd, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(BitwiseOr, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(BitwiseXor, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(ShiftLeft, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(ShiftRight, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(ShiftRightLogical, BUILTIN, kNoExtraICState, BinaryOp) \
|
||||
TFS(LessThan, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(LessThanOrEqual, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(GreaterThan, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(GreaterThanOrEqual, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(Equal, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(NotEqual, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(StrictEqual, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(StrictNotEqual, BUILTIN, kNoExtraICState, Compare) \
|
||||
\
|
||||
/* Object */ \
|
||||
CPP(ObjectAssign) \
|
||||
@ -513,6 +537,10 @@ namespace internal {
|
||||
CPP(ObjectSeal) \
|
||||
CPP(ObjectValues) \
|
||||
\
|
||||
TFS(HasProperty, BUILTIN, kNoExtraICState, HasProperty) \
|
||||
TFS(InstanceOf, BUILTIN, kNoExtraICState, Compare) \
|
||||
TFS(ForInFilter, BUILTIN, kNoExtraICState, ForInFilter) \
|
||||
\
|
||||
/* Proxy */ \
|
||||
CPP(ProxyConstructor) \
|
||||
CPP(ProxyConstructor_ConstructStub) \
|
||||
|
@ -2485,8 +2485,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(edi);
|
||||
__ mov(eax, ecx);
|
||||
__ Push(esi);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(esi);
|
||||
__ mov(ecx, eax);
|
||||
__ Pop(edi);
|
||||
|
@ -2455,8 +2455,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(a0, a1);
|
||||
__ mov(a0, a3);
|
||||
__ Push(cp);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(cp);
|
||||
__ mov(a3, v0);
|
||||
__ Pop(a0, a1);
|
||||
|
@ -2450,8 +2450,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(a0, a1);
|
||||
__ mov(a0, a3);
|
||||
__ Push(cp);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(cp);
|
||||
__ mov(a3, v0);
|
||||
__ Pop(a0, a1);
|
||||
|
@ -2507,8 +2507,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(r3, r4);
|
||||
__ mr(r3, r6);
|
||||
__ Push(cp);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(cp);
|
||||
__ mr(r6, r3);
|
||||
__ Pop(r3, r4);
|
||||
|
@ -2516,8 +2516,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(r2, r3);
|
||||
__ LoadRR(r2, r5);
|
||||
__ Push(cp);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(cp);
|
||||
__ LoadRR(r5, r2);
|
||||
__ Pop(r2, r3);
|
||||
|
@ -2583,8 +2583,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(rdi);
|
||||
__ movp(rax, rcx);
|
||||
__ Push(rsi);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(rsi);
|
||||
__ movp(rcx, rax);
|
||||
__ Pop(rdi);
|
||||
|
@ -2509,8 +2509,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ Push(edi);
|
||||
__ mov(eax, ecx);
|
||||
__ Push(esi);
|
||||
ToObjectStub stub(masm->isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(masm->isolate()->builtins()->ToObject(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Pop(esi);
|
||||
__ mov(ecx, eax);
|
||||
__ Pop(edi);
|
||||
|
@ -153,12 +153,6 @@ Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::InstanceOf(Isolate* isolate) {
|
||||
InstanceOfStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::GetProperty(Isolate* isolate) {
|
||||
GetPropertyStub stub(isolate);
|
||||
@ -189,36 +183,12 @@ Callable CodeFactory::StringToNumber(Isolate* isolate) {
|
||||
TypeConversionDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ToString(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ToString(),
|
||||
TypeConversionDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ToName(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ToName(),
|
||||
TypeConversionDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ToInteger(Isolate* isolate) {
|
||||
ToIntegerStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ToLength(Isolate* isolate) {
|
||||
ToLengthStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ToObject(Isolate* isolate) {
|
||||
ToObjectStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate,
|
||||
ToPrimitiveHint hint) {
|
||||
@ -251,71 +221,45 @@ Callable CodeFactory::RegExpExec(Isolate* isolate) {
|
||||
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Add(Isolate* isolate) {
|
||||
AddStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
#define DECLARE_TFS(Name, Kind, Extra, InterfaceDescriptor) \
|
||||
typedef InterfaceDescriptor##Descriptor Name##Descriptor;
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, DECLARE_TFS,
|
||||
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
|
||||
#undef DECLARE_TFS
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Subtract(Isolate* isolate) {
|
||||
SubtractStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
#define TFS_BUILTIN(Name) \
|
||||
Callable CodeFactory::Name(Isolate* isolate) { \
|
||||
Handle<Code> code(isolate->builtins()->Name()); \
|
||||
return Callable(code, Name##Descriptor(isolate)); \
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Multiply(Isolate* isolate) {
|
||||
MultiplyStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Divide(Isolate* isolate) {
|
||||
DivideStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Modulus(Isolate* isolate) {
|
||||
ModulusStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ShiftRight(Isolate* isolate) {
|
||||
ShiftRightStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ShiftRightLogical(Isolate* isolate) {
|
||||
ShiftRightLogicalStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ShiftLeft(Isolate* isolate) {
|
||||
ShiftLeftStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::BitwiseAnd(Isolate* isolate) {
|
||||
BitwiseAndStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::BitwiseOr(Isolate* isolate) {
|
||||
BitwiseOrStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::BitwiseXor(Isolate* isolate) {
|
||||
BitwiseXorStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
TFS_BUILTIN(ToString)
|
||||
TFS_BUILTIN(Add)
|
||||
TFS_BUILTIN(Subtract)
|
||||
TFS_BUILTIN(Multiply)
|
||||
TFS_BUILTIN(Divide)
|
||||
TFS_BUILTIN(Modulus)
|
||||
TFS_BUILTIN(BitwiseAnd)
|
||||
TFS_BUILTIN(BitwiseOr)
|
||||
TFS_BUILTIN(BitwiseXor)
|
||||
TFS_BUILTIN(ShiftLeft)
|
||||
TFS_BUILTIN(ShiftRight)
|
||||
TFS_BUILTIN(ShiftRightLogical)
|
||||
TFS_BUILTIN(LessThan)
|
||||
TFS_BUILTIN(LessThanOrEqual)
|
||||
TFS_BUILTIN(GreaterThan)
|
||||
TFS_BUILTIN(GreaterThanOrEqual)
|
||||
TFS_BUILTIN(Equal)
|
||||
TFS_BUILTIN(NotEqual)
|
||||
TFS_BUILTIN(StrictEqual)
|
||||
TFS_BUILTIN(StrictNotEqual)
|
||||
TFS_BUILTIN(HasProperty)
|
||||
TFS_BUILTIN(ToInteger)
|
||||
TFS_BUILTIN(ToLength)
|
||||
TFS_BUILTIN(ToObject)
|
||||
TFS_BUILTIN(Typeof)
|
||||
TFS_BUILTIN(InstanceOf)
|
||||
TFS_BUILTIN(ForInFilter)
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Inc(Isolate* isolate) {
|
||||
@ -329,54 +273,6 @@ Callable CodeFactory::Dec(Isolate* isolate) {
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::LessThan(Isolate* isolate) {
|
||||
LessThanStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::LessThanOrEqual(Isolate* isolate) {
|
||||
LessThanOrEqualStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::GreaterThan(Isolate* isolate) {
|
||||
GreaterThanStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::GreaterThanOrEqual(Isolate* isolate) {
|
||||
GreaterThanOrEqualStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Equal(Isolate* isolate) {
|
||||
EqualStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::NotEqual(Isolate* isolate) {
|
||||
NotEqualStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StrictEqual(Isolate* isolate) {
|
||||
StrictEqualStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StrictNotEqual(Isolate* isolate) {
|
||||
StrictNotEqualStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
|
||||
PretenureFlag pretenure_flag) {
|
||||
@ -456,12 +352,6 @@ Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
|
||||
ResumeGeneratorDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Typeof(Isolate* isolate) {
|
||||
TypeofStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::FastCloneRegExp(Isolate* isolate) {
|
||||
FastCloneRegExpStub stub(isolate);
|
||||
@ -584,18 +474,6 @@ Callable CodeFactory::ConstructFunction(Isolate* isolate) {
|
||||
ConstructTrampolineDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::HasProperty(Isolate* isolate) {
|
||||
HasPropertyStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ForInFilter(Isolate* isolate) {
|
||||
ForInFilterStub stub(isolate);
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
|
||||
TailCallMode tail_call_mode,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -862,6 +862,36 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
FixedArray::kHeaderSize);
|
||||
}
|
||||
|
||||
enum RelationalComparisonMode {
|
||||
kLessThan,
|
||||
kLessThanOrEqual,
|
||||
kGreaterThan,
|
||||
kGreaterThanOrEqual
|
||||
};
|
||||
|
||||
compiler::Node* RelationalComparison(RelationalComparisonMode mode,
|
||||
compiler::Node* lhs, compiler::Node* rhs,
|
||||
compiler::Node* context);
|
||||
|
||||
enum ResultMode { kDontNegateResult, kNegateResult };
|
||||
|
||||
compiler::Node* Equal(ResultMode mode, compiler::Node* lhs,
|
||||
compiler::Node* rhs, compiler::Node* context);
|
||||
|
||||
compiler::Node* StrictEqual(ResultMode mode, compiler::Node* lhs,
|
||||
compiler::Node* rhs, compiler::Node* context);
|
||||
|
||||
compiler::Node* HasProperty(
|
||||
compiler::Node* object, compiler::Node* key, compiler::Node* context,
|
||||
Runtime::FunctionId fallback_runtime_function_id = Runtime::kHasProperty);
|
||||
compiler::Node* ForInFilter(compiler::Node* key, compiler::Node* object,
|
||||
compiler::Node* context);
|
||||
|
||||
compiler::Node* Typeof(compiler::Node* value, compiler::Node* context);
|
||||
|
||||
compiler::Node* InstanceOf(compiler::Node* object, compiler::Node* callable,
|
||||
compiler::Node* context);
|
||||
|
||||
private:
|
||||
enum ElementSupport { kOnlyProperties, kSupportElements };
|
||||
|
||||
|
2840
src/code-stubs.cc
2840
src/code-stubs.cc
File diff suppressed because it is too large
Load Diff
237
src/code-stubs.h
237
src/code-stubs.h
@ -108,22 +108,11 @@ class ObjectLiteral;
|
||||
V(CreateAllocationSite) \
|
||||
V(CreateWeakCell) \
|
||||
V(StringLength) \
|
||||
V(Add) \
|
||||
V(AddWithFeedback) \
|
||||
V(Subtract) \
|
||||
V(SubtractWithFeedback) \
|
||||
V(Multiply) \
|
||||
V(MultiplyWithFeedback) \
|
||||
V(Divide) \
|
||||
V(DivideWithFeedback) \
|
||||
V(Modulus) \
|
||||
V(ModulusWithFeedback) \
|
||||
V(ShiftRight) \
|
||||
V(ShiftRightLogical) \
|
||||
V(ShiftLeft) \
|
||||
V(BitwiseAnd) \
|
||||
V(BitwiseOr) \
|
||||
V(BitwiseXor) \
|
||||
V(Inc) \
|
||||
V(InternalArrayNoArgumentConstructor) \
|
||||
V(InternalArraySingleArgumentConstructor) \
|
||||
@ -134,23 +123,10 @@ class ObjectLiteral;
|
||||
V(FastCloneShallowObject) \
|
||||
V(FastNewClosure) \
|
||||
V(FastNewFunctionContext) \
|
||||
V(InstanceOf) \
|
||||
V(LessThan) \
|
||||
V(LessThanOrEqual) \
|
||||
V(GreaterThan) \
|
||||
V(GreaterThanOrEqual) \
|
||||
V(Equal) \
|
||||
V(NotEqual) \
|
||||
V(KeyedLoadSloppyArguments) \
|
||||
V(KeyedStoreSloppyArguments) \
|
||||
V(LoadScriptContextField) \
|
||||
V(StoreScriptContextField) \
|
||||
V(StrictEqual) \
|
||||
V(StrictNotEqual) \
|
||||
V(ToInteger) \
|
||||
V(ToLength) \
|
||||
V(HasProperty) \
|
||||
V(ForInFilter) \
|
||||
V(GetProperty) \
|
||||
V(LoadICTF) \
|
||||
V(KeyedLoadICTF) \
|
||||
@ -164,8 +140,6 @@ class ObjectLiteral;
|
||||
V(LoadApiGetter) \
|
||||
V(LoadIndexedInterceptor) \
|
||||
V(GrowArrayElements) \
|
||||
V(ToObject) \
|
||||
V(Typeof) \
|
||||
/* These are only called from FGC and */ \
|
||||
/* can be removed when we use ignition */ \
|
||||
/* only */ \
|
||||
@ -756,14 +730,6 @@ class StringLengthStub : public TurboFanCodeStub {
|
||||
DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class AddStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit AddStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Add, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class AddWithFeedbackStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit AddWithFeedbackStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
@ -773,14 +739,6 @@ class AddWithFeedbackStub final : public TurboFanCodeStub {
|
||||
TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class SubtractStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit SubtractStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Subtract, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class SubtractWithFeedbackStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit SubtractWithFeedbackStub(Isolate* isolate)
|
||||
@ -791,14 +749,6 @@ class SubtractWithFeedbackStub final : public TurboFanCodeStub {
|
||||
TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class MultiplyStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit MultiplyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Multiply, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class MultiplyWithFeedbackStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit MultiplyWithFeedbackStub(Isolate* isolate)
|
||||
@ -809,14 +759,6 @@ class MultiplyWithFeedbackStub final : public TurboFanCodeStub {
|
||||
TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class DivideStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit DivideStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Divide, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class DivideWithFeedbackStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit DivideWithFeedbackStub(Isolate* isolate)
|
||||
@ -827,14 +769,6 @@ class DivideWithFeedbackStub final : public TurboFanCodeStub {
|
||||
TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ModulusStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ModulusStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Modulus, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ModulusWithFeedbackStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ModulusWithFeedbackStub(Isolate* isolate)
|
||||
@ -845,55 +779,6 @@ class ModulusWithFeedbackStub final : public TurboFanCodeStub {
|
||||
TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ShiftRightStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ShiftRightStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ShiftRight, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ShiftRightLogicalStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ShiftRightLogicalStub(Isolate* isolate)
|
||||
: TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ShiftRightLogical, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ShiftLeftStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ShiftLeftStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ShiftLeft, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class BitwiseAndStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit BitwiseAndStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(BitwiseAnd, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class BitwiseOrStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit BitwiseOrStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(BitwiseOr, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class BitwiseXorStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit BitwiseXorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(BitwiseXor, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class IncStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit IncStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
@ -910,96 +795,6 @@ class DecStub final : public TurboFanCodeStub {
|
||||
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB_WITH_FEEDBACK(Dec, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class InstanceOfStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit InstanceOfStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
private:
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(InstanceOf, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class LessThanStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit LessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(LessThan, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class LessThanOrEqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit LessThanOrEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(LessThanOrEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class GreaterThanStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit GreaterThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(GreaterThan, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class GreaterThanOrEqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit GreaterThanOrEqualStub(Isolate* isolate)
|
||||
: TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(GreaterThanOrEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class EqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit EqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Equal, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class NotEqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit NotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(NotEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class StrictEqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit StrictEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(StrictEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class StrictNotEqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit StrictNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ToIntegerStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ToIntegerStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
|
||||
DEFINE_TURBOFAN_CODE_STUB(ToInteger, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ToLengthStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ToLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
|
||||
DEFINE_TURBOFAN_CODE_STUB(ToLength, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class StoreInterceptorStub : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit StoreInterceptorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
@ -1025,23 +820,6 @@ class LoadIndexedInterceptorStub : public TurboFanCodeStub {
|
||||
DEFINE_TURBOFAN_CODE_STUB(LoadIndexedInterceptor, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
// ES6 section 12.10.3 "in" operator evaluation.
|
||||
class HasPropertyStub : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit HasPropertyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(HasProperty);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(HasProperty, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ForInFilterStub : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ForInFilterStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ForInFilter);
|
||||
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ForInFilter, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
// ES6 [[Get]] operation.
|
||||
class GetPropertyStub : public TurboFanCodeStub {
|
||||
public:
|
||||
@ -1078,14 +856,6 @@ class NumberToStringStub final : public HydrogenCodeStub {
|
||||
DEFINE_HYDROGEN_CODE_STUB(NumberToString, HydrogenCodeStub);
|
||||
};
|
||||
|
||||
class TypeofStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit TypeofStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Typeof);
|
||||
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB(Typeof, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class FastNewClosureStub : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit FastNewClosureStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
@ -3116,13 +2886,6 @@ class SubStringStub : public TurboFanCodeStub {
|
||||
DEFINE_CODE_STUB(SubString, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ToObjectStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ToObjectStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
|
||||
DEFINE_TURBOFAN_CODE_STUB(ToObject, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
#undef DEFINE_CALL_INTERFACE_DESCRIPTOR
|
||||
#undef DEFINE_PLATFORM_CODE_STUB
|
||||
|
@ -5261,11 +5261,10 @@ void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt,
|
||||
}
|
||||
set_current_block(if_slow);
|
||||
{
|
||||
ForInFilterStub stub(isolate());
|
||||
Callable callable = CodeFactory::ForInFilter(isolate());
|
||||
HValue* values[] = {context(), key, enumerable};
|
||||
HConstant* stub_value = Add<HConstant>(stub.GetCode());
|
||||
Push(Add<HCallWithDescriptor>(stub_value, 0,
|
||||
stub.GetCallInterfaceDescriptor(),
|
||||
HConstant* stub_value = Add<HConstant>(callable.code());
|
||||
Push(Add<HCallWithDescriptor>(stub_value, 0, callable.descriptor(),
|
||||
ArrayVector(values)));
|
||||
Add<HSimulate>(stmt->FilterId());
|
||||
FinishCurrentBlock(New<HCompareObjectEqAndBranch>(
|
||||
|
@ -1016,8 +1016,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
|
||||
__ b(eq, &exit);
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -1118,10 +1117,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ str(r2, FieldMemOperand(r3, FixedArray::OffsetOfElementAt(vector_index)));
|
||||
|
||||
// r0 contains the key. The receiver in r1 is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub filter_stub(isolate());
|
||||
__ CallStub(&filter_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex);
|
||||
@ -3050,8 +3048,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ mov(r3, r0);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(r0);
|
||||
break;
|
||||
}
|
||||
@ -3420,8 +3417,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(r1);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(r0, Heap::kTrueValueRootIndex);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
@ -1012,8 +1012,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit);
|
||||
__ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit);
|
||||
__ Bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ Bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -1108,10 +1107,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ Str(x10, FieldMemOperand(x3, FixedArray::OffsetOfElementAt(vector_index)));
|
||||
|
||||
// x0 contains the key. The receiver in x1 is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub filter_stub(isolate());
|
||||
__ CallStub(&filter_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex);
|
||||
@ -2971,8 +2969,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ Mov(x3, x0);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(x0);
|
||||
break;
|
||||
}
|
||||
@ -3347,8 +3344,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(x1);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(x0, Heap::kTrueValueRootIndex);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
@ -955,8 +955,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ cmp(eax, isolate()->factory()->null_value());
|
||||
__ j(equal, &exit);
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -1045,10 +1044,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
||||
|
||||
// eax contains the key. The receiver in ebx is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub filter_stub(isolate());
|
||||
__ CallStub(&filter_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ JumpIfRoot(result_register(), Heap::kUndefinedValueRootIndex,
|
||||
@ -2946,8 +2944,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ mov(ebx, eax);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(eax);
|
||||
break;
|
||||
}
|
||||
@ -3317,8 +3314,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(edx);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ cmp(eax, isolate()->factory()->true_value());
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
@ -1012,8 +1012,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ LoadRoot(at, Heap::kUndefinedValueRootIndex); // In delay slot.
|
||||
__ Branch(&exit, eq, a0, Operand(at));
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ mov(a0, v0);
|
||||
__ bind(&done_convert);
|
||||
@ -1113,10 +1112,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
__ mov(a0, result_register());
|
||||
// a0 contains the key. The receiver in a1 is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub filter_stub(isolate());
|
||||
__ CallStub(&filter_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
|
||||
@ -3057,8 +3055,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ mov(a3, v0);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(v0);
|
||||
break;
|
||||
}
|
||||
@ -3427,8 +3424,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
SetExpressionPosition(expr);
|
||||
__ mov(a0, result_register());
|
||||
PopOperand(a1);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ LoadRoot(at, Heap::kTrueValueRootIndex);
|
||||
Split(eq, v0, Operand(at), if_true, if_false, fall_through);
|
||||
|
@ -1012,8 +1012,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ LoadRoot(at, Heap::kUndefinedValueRootIndex); // In delay slot.
|
||||
__ Branch(&exit, eq, a0, Operand(at));
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ mov(a0, v0);
|
||||
__ bind(&done_convert);
|
||||
@ -1114,10 +1113,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
|
||||
__ mov(a0, result_register());
|
||||
// a0 contains the key. The receiver in a1 is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub filter_stub(isolate());
|
||||
__ CallStub(&filter_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
|
||||
@ -3057,8 +3055,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ mov(a3, v0);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(v0);
|
||||
break;
|
||||
}
|
||||
@ -3427,8 +3424,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
SetExpressionPosition(expr);
|
||||
__ mov(a0, result_register());
|
||||
PopOperand(a1);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ LoadRoot(a4, Heap::kTrueValueRootIndex);
|
||||
Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
|
||||
|
@ -976,8 +976,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
|
||||
__ beq(&exit);
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -3048,8 +3047,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ mr(r6, r3);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(r3);
|
||||
break;
|
||||
}
|
||||
@ -3419,8 +3417,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(r4);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(r3, Heap::kTrueValueRootIndex);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
@ -946,8 +946,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
__ beq(&exit);
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -2970,8 +2969,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ LoadRR(r5, r2);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(r2);
|
||||
break;
|
||||
}
|
||||
@ -3335,8 +3333,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(r3);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(r2, Heap::kTrueValueRootIndex);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
@ -971,8 +971,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
|
||||
__ j(equal, &exit);
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -1071,11 +1070,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ Move(FieldOperand(rdx, FixedArray::OffsetOfElementAt(vector_index)),
|
||||
TypeFeedbackVector::MegamorphicSentinel(isolate()));
|
||||
|
||||
// rax contains the key. The receiver in rbx is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// rax contains the key. The receiver in rbx is the second argument to
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub has_stub(isolate());
|
||||
__ CallStub(&has_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ JumpIfRoot(result_register(), Heap::kUndefinedValueRootIndex,
|
||||
@ -2937,8 +2935,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ movp(rbx, rax);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(rax);
|
||||
break;
|
||||
}
|
||||
@ -3306,8 +3303,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(rdx);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ CompareRoot(rax, Heap::kTrueValueRootIndex);
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
@ -947,8 +947,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
__ cmp(eax, isolate()->factory()->null_value());
|
||||
__ j(equal, &exit);
|
||||
__ bind(&convert);
|
||||
ToObjectStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
__ bind(&done_convert);
|
||||
PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
|
||||
@ -1037,10 +1036,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
|
||||
|
||||
// eax contains the key. The receiver in ebx is the second argument to the
|
||||
// ForInFilterStub. ForInFilter returns undefined if the receiver doesn't
|
||||
// ForInFilter. ForInFilter returns undefined if the receiver doesn't
|
||||
// have the key or returns the name-converted key.
|
||||
ForInFilterStub filter_stub(isolate());
|
||||
__ CallStub(&filter_stub);
|
||||
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
|
||||
RestoreContext();
|
||||
PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
|
||||
__ JumpIfRoot(result_register(), Heap::kUndefinedValueRootIndex,
|
||||
@ -2938,8 +2936,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitForTypeofValue(expr->expression());
|
||||
}
|
||||
__ mov(ebx, eax);
|
||||
TypeofStub typeof_stub(isolate());
|
||||
__ CallStub(&typeof_stub);
|
||||
__ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET);
|
||||
context()->Plug(eax);
|
||||
break;
|
||||
}
|
||||
@ -3309,8 +3306,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitForAccumulatorValue(expr->right());
|
||||
SetExpressionPosition(expr);
|
||||
PopOperand(edx);
|
||||
InstanceOfStub stub(isolate());
|
||||
__ CallStub(&stub);
|
||||
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
|
||||
__ cmp(eax, isolate()->factory()->true_value());
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
@ -904,14 +904,24 @@ void Interpreter::DoPopContext(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// TODO(mythria): Remove this function once all BinaryOps record type feedback.
|
||||
template <class Generator>
|
||||
void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) {
|
||||
// TODO(mythria): Remove this function once all CompareOps record type feedback.
|
||||
void Interpreter::DoCompareOp(Token::Value compare_op,
|
||||
InterpreterAssembler* assembler) {
|
||||
Node* reg_index = __ BytecodeOperandReg(0);
|
||||
Node* lhs = __ LoadRegister(reg_index);
|
||||
Node* rhs = __ GetAccumulator();
|
||||
Node* context = __ GetContext();
|
||||
Node* result = Generator::Generate(assembler, lhs, rhs, context);
|
||||
Node* result;
|
||||
switch (compare_op) {
|
||||
case Token::IN:
|
||||
result = assembler->HasProperty(rhs, lhs, context);
|
||||
break;
|
||||
case Token::INSTANCEOF:
|
||||
result = assembler->InstanceOf(lhs, rhs, context);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
__ SetAccumulator(result);
|
||||
__ Dispatch();
|
||||
}
|
||||
@ -930,8 +940,8 @@ void Interpreter::DoBinaryOpWithFeedback(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
template <class Generator>
|
||||
void Interpreter::DoCompareOpWithFeedback(InterpreterAssembler* assembler) {
|
||||
void Interpreter::DoCompareOpWithFeedback(Token::Value compare_op,
|
||||
InterpreterAssembler* assembler) {
|
||||
Node* reg_index = __ BytecodeOperandReg(0);
|
||||
Node* lhs = __ LoadRegister(reg_index);
|
||||
Node* rhs = __ GetAccumulator();
|
||||
@ -999,7 +1009,39 @@ void Interpreter::DoCompareOpWithFeedback(InterpreterAssembler* assembler) {
|
||||
__ Goto(&skip_feedback_update);
|
||||
|
||||
__ Bind(&skip_feedback_update);
|
||||
Node* result = Generator::Generate(assembler, lhs, rhs, context);
|
||||
Node* result;
|
||||
switch (compare_op) {
|
||||
case Token::EQ:
|
||||
result = assembler->Equal(CodeStubAssembler::kDontNegateResult, lhs, rhs,
|
||||
context);
|
||||
break;
|
||||
case Token::NE:
|
||||
result =
|
||||
assembler->Equal(CodeStubAssembler::kNegateResult, lhs, rhs, context);
|
||||
break;
|
||||
case Token::EQ_STRICT:
|
||||
result = assembler->StrictEqual(CodeStubAssembler::kDontNegateResult, lhs,
|
||||
rhs, context);
|
||||
break;
|
||||
case Token::LT:
|
||||
result = assembler->RelationalComparison(CodeStubAssembler::kLessThan,
|
||||
lhs, rhs, context);
|
||||
break;
|
||||
case Token::GT:
|
||||
result = assembler->RelationalComparison(CodeStubAssembler::kGreaterThan,
|
||||
lhs, rhs, context);
|
||||
break;
|
||||
case Token::LTE:
|
||||
result = assembler->RelationalComparison(
|
||||
CodeStubAssembler::kLessThanOrEqual, lhs, rhs, context);
|
||||
break;
|
||||
case Token::GTE:
|
||||
result = assembler->RelationalComparison(
|
||||
CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
__ SetAccumulator(result);
|
||||
__ Dispatch();
|
||||
}
|
||||
@ -1392,15 +1434,6 @@ Node* Interpreter::BuildUnaryOp(Callable callable,
|
||||
return __ CallStub(callable.descriptor(), target, context, accumulator);
|
||||
}
|
||||
|
||||
template <class Generator>
|
||||
void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) {
|
||||
Node* value = __ GetAccumulator();
|
||||
Node* context = __ GetContext();
|
||||
Node* result = Generator::Generate(assembler, value, context);
|
||||
__ SetAccumulator(result);
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
template <class Generator>
|
||||
void Interpreter::DoUnaryOpWithFeedback(InterpreterAssembler* assembler) {
|
||||
Node* value = __ GetAccumulator();
|
||||
@ -1520,7 +1553,11 @@ void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) {
|
||||
// Load the accumulator with the string representating type of the
|
||||
// object in the accumulator.
|
||||
void Interpreter::DoTypeOf(InterpreterAssembler* assembler) {
|
||||
DoUnaryOp<TypeofStub>(assembler);
|
||||
Node* value = __ GetAccumulator();
|
||||
Node* context = __ GetContext();
|
||||
Node* result = assembler->Typeof(value, context);
|
||||
__ SetAccumulator(result);
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
void Interpreter::DoDelete(Runtime::FunctionId function_id,
|
||||
@ -1698,35 +1735,35 @@ void Interpreter::DoNew(InterpreterAssembler* assembler) {
|
||||
//
|
||||
// Test if the value in the <src> register equals the accumulator.
|
||||
void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<EqualStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::EQ, assembler);
|
||||
}
|
||||
|
||||
// TestNotEqual <src>
|
||||
//
|
||||
// Test if the value in the <src> register is not equal to the accumulator.
|
||||
void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<NotEqualStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::NE, assembler);
|
||||
}
|
||||
|
||||
// TestEqualStrict <src>
|
||||
//
|
||||
// Test if the value in the <src> register is strictly equal to the accumulator.
|
||||
void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<StrictEqualStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::EQ_STRICT, assembler);
|
||||
}
|
||||
|
||||
// TestLessThan <src>
|
||||
//
|
||||
// Test if the value in the <src> register is less than the accumulator.
|
||||
void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<LessThanStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::LT, assembler);
|
||||
}
|
||||
|
||||
// TestGreaterThan <src>
|
||||
//
|
||||
// Test if the value in the <src> register is greater than the accumulator.
|
||||
void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<GreaterThanStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::GT, assembler);
|
||||
}
|
||||
|
||||
// TestLessThanOrEqual <src>
|
||||
@ -1734,7 +1771,7 @@ void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
|
||||
// Test if the value in the <src> register is less than or equal to the
|
||||
// accumulator.
|
||||
void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<LessThanOrEqualStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::LTE, assembler);
|
||||
}
|
||||
|
||||
// TestGreaterThanOrEqual <src>
|
||||
@ -1742,7 +1779,7 @@ void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
|
||||
// Test if the value in the <src> register is greater than or equal to the
|
||||
// accumulator.
|
||||
void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
|
||||
DoCompareOpWithFeedback<GreaterThanOrEqualStub>(assembler);
|
||||
DoCompareOpWithFeedback(Token::Value::GTE, assembler);
|
||||
}
|
||||
|
||||
// TestIn <src>
|
||||
@ -1750,7 +1787,7 @@ void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
|
||||
// Test if the object referenced by the register operand is a property of the
|
||||
// object referenced by the accumulator.
|
||||
void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
|
||||
DoBinaryOp<HasPropertyStub>(assembler);
|
||||
DoCompareOp(Token::IN, assembler);
|
||||
}
|
||||
|
||||
// TestInstanceOf <src>
|
||||
@ -1758,7 +1795,7 @@ void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
|
||||
// Test if the object referenced by the <src> register is an an instance of type
|
||||
// referenced by the accumulator.
|
||||
void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
|
||||
DoBinaryOp<InstanceOfStub>(assembler);
|
||||
DoCompareOp(Token::INSTANCEOF, assembler);
|
||||
}
|
||||
|
||||
// Jump <imm>
|
||||
|
@ -76,18 +76,14 @@ class Interpreter {
|
||||
BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR)
|
||||
#undef DECLARE_BYTECODE_HANDLER_GENERATOR
|
||||
|
||||
// Generates code to perform the binary operation via |Generator|.
|
||||
template <class Generator>
|
||||
void DoBinaryOp(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform the binary operation via |Generator|.
|
||||
template <class Generator>
|
||||
void DoBinaryOpWithFeedback(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform the comparison via |Generator| while gathering
|
||||
// type feedback.
|
||||
template <class Generator>
|
||||
void DoCompareOpWithFeedback(InterpreterAssembler* assembler);
|
||||
void DoCompareOpWithFeedback(Token::Value compare_op,
|
||||
InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform the bitwise binary operation corresponding to
|
||||
// |bitwise_op| while gathering type feedback.
|
||||
@ -99,10 +95,6 @@ class Interpreter {
|
||||
template <class Generator>
|
||||
void DoBinaryOpWithImmediate(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform the unary operation via |Generator|.
|
||||
template <class Generator>
|
||||
void DoUnaryOp(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform the unary operation via |Generator| while
|
||||
// gatering type feedback.
|
||||
template <class Generator>
|
||||
|
Loading…
Reference in New Issue
Block a user