Inline code generation for %_IsTypedArray
This patch implements %_IsTypedArray in fullcodegen, Hydrogen and Turbofan in order to implement fast type checks to enable ES6 TypedArray features and semantics efficiently. R=adamk,titzer LOG=Y BUG=v8:4085 Review URL: https://codereview.chromium.org/1183213002 Cr-Commit-Position: refs/heads/master@{#29033}
This commit is contained in:
parent
e1efb4be11
commit
350a70e5ef
@ -3650,6 +3650,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(r0, if_false);
|
||||||
|
__ CompareObjectType(r0, r1, r1, JS_TYPED_ARRAY_TYPE);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(eq, if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -3350,6 +3350,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(x0, if_false);
|
||||||
|
__ CompareObjectType(x0, x10, x11, JS_TYPED_ARRAY_TYPE);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(eq, if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -46,6 +46,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
|||||||
return ReduceIncrementStatsCounter(node);
|
return ReduceIncrementStatsCounter(node);
|
||||||
case Runtime::kInlineIsArray:
|
case Runtime::kInlineIsArray:
|
||||||
return ReduceIsInstanceType(node, JS_ARRAY_TYPE);
|
return ReduceIsInstanceType(node, JS_ARRAY_TYPE);
|
||||||
|
case Runtime::kInlineIsTypedArray:
|
||||||
|
return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
|
||||||
case Runtime::kInlineIsFunction:
|
case Runtime::kInlineIsFunction:
|
||||||
return ReduceIsInstanceType(node, JS_FUNCTION_TYPE);
|
return ReduceIsInstanceType(node, JS_FUNCTION_TYPE);
|
||||||
case Runtime::kInlineIsNonNegativeSmi:
|
case Runtime::kInlineIsNonNegativeSmi:
|
||||||
|
@ -1599,6 +1599,7 @@ Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
|
|||||||
case Runtime::kInlineIsSmi:
|
case Runtime::kInlineIsSmi:
|
||||||
case Runtime::kInlineIsNonNegativeSmi:
|
case Runtime::kInlineIsNonNegativeSmi:
|
||||||
case Runtime::kInlineIsArray:
|
case Runtime::kInlineIsArray:
|
||||||
|
case Runtime::kInlineIsTypedArray:
|
||||||
case Runtime::kInlineIsMinusZero:
|
case Runtime::kInlineIsMinusZero:
|
||||||
case Runtime::kInlineIsFunction:
|
case Runtime::kInlineIsFunction:
|
||||||
case Runtime::kInlineIsRegExp:
|
case Runtime::kInlineIsRegExp:
|
||||||
|
@ -521,6 +521,7 @@ class FullCodeGenerator: public AstVisitor {
|
|||||||
F(IsSmi) \
|
F(IsSmi) \
|
||||||
F(IsNonNegativeSmi) \
|
F(IsNonNegativeSmi) \
|
||||||
F(IsArray) \
|
F(IsArray) \
|
||||||
|
F(IsTypedArray) \
|
||||||
F(IsRegExp) \
|
F(IsRegExp) \
|
||||||
F(IsJSProxy) \
|
F(IsJSProxy) \
|
||||||
F(IsConstructCall) \
|
F(IsConstructCall) \
|
||||||
|
@ -104,7 +104,7 @@ function ConstructTypedArrayLike(typedArray, arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function TypedArrayCopyWithin(target, start, end) {
|
function TypedArrayCopyWithin(target, start, end) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ function TypedArrayCopyWithin(target, start, end) {
|
|||||||
|
|
||||||
// ES6 draft 05-05-15, section 22.2.3.7
|
// ES6 draft 05-05-15, section 22.2.3.7
|
||||||
function TypedArrayEvery(f, receiver) {
|
function TypedArrayEvery(f, receiver) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ function TypedArrayEvery(f, receiver) {
|
|||||||
|
|
||||||
// ES6 draft 08-24-14, section 22.2.3.12
|
// ES6 draft 08-24-14, section 22.2.3.12
|
||||||
function TypedArrayForEach(f, receiver) {
|
function TypedArrayForEach(f, receiver) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ function TypedArrayForEach(f, receiver) {
|
|||||||
|
|
||||||
// ES6 draft 04-05-14 section 22.2.3.8
|
// ES6 draft 04-05-14 section 22.2.3.8
|
||||||
function TypedArrayFill(value, start, end) {
|
function TypedArrayFill(value, start, end) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ function TypedArrayFill(value, start, end) {
|
|||||||
|
|
||||||
// ES6 draft 07-15-13, section 22.2.3.9
|
// ES6 draft 07-15-13, section 22.2.3.9
|
||||||
function TypedArrayFilter(predicate, thisArg) {
|
function TypedArrayFilter(predicate, thisArg) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
var array = InnerArrayFilter(predicate, thisArg, this, length);
|
var array = InnerArrayFilter(predicate, thisArg, this, length);
|
||||||
@ -155,7 +155,7 @@ function TypedArrayFilter(predicate, thisArg) {
|
|||||||
|
|
||||||
// ES6 draft 07-15-13, section 22.2.3.10
|
// ES6 draft 07-15-13, section 22.2.3.10
|
||||||
function TypedArrayFind(predicate, thisArg) {
|
function TypedArrayFind(predicate, thisArg) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ function TypedArrayFind(predicate, thisArg) {
|
|||||||
|
|
||||||
// ES6 draft 07-15-13, section 22.2.3.11
|
// ES6 draft 07-15-13, section 22.2.3.11
|
||||||
function TypedArrayFindIndex(predicate, thisArg) {
|
function TypedArrayFindIndex(predicate, thisArg) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ function TypedArrayFindIndex(predicate, thisArg) {
|
|||||||
|
|
||||||
// ES6 draft 05-18-15, section 22.2.3.21
|
// ES6 draft 05-18-15, section 22.2.3.21
|
||||||
function TypedArrayReverse() {
|
function TypedArrayReverse() {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ function TypedArrayComparefn(x, y) {
|
|||||||
|
|
||||||
// ES6 draft 05-18-15, section 22.2.3.25
|
// ES6 draft 05-18-15, section 22.2.3.25
|
||||||
function TypedArraySort(comparefn) {
|
function TypedArraySort(comparefn) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ function TypedArraySort(comparefn) {
|
|||||||
|
|
||||||
// ES6 section 22.2.3.13
|
// ES6 section 22.2.3.13
|
||||||
function TypedArrayIndexOf(element, index) {
|
function TypedArrayIndexOf(element, index) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ function TypedArrayIndexOf(element, index) {
|
|||||||
|
|
||||||
// ES6 section 22.2.3.16
|
// ES6 section 22.2.3.16
|
||||||
function TypedArrayLastIndexOf(element, index) {
|
function TypedArrayLastIndexOf(element, index) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ function TypedArrayLastIndexOf(element, index) {
|
|||||||
|
|
||||||
// ES6 draft 07-15-13, section 22.2.3.18
|
// ES6 draft 07-15-13, section 22.2.3.18
|
||||||
function TypedArrayMap(predicate, thisArg) {
|
function TypedArrayMap(predicate, thisArg) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
// TODO(littledan): Preallocate rather than making an intermediate
|
// TODO(littledan): Preallocate rather than making an intermediate
|
||||||
// InternalArray, for better performance.
|
// InternalArray, for better performance.
|
||||||
@ -255,7 +255,7 @@ function TypedArrayMap(predicate, thisArg) {
|
|||||||
|
|
||||||
// ES6 draft 05-05-15, section 22.2.3.24
|
// ES6 draft 05-05-15, section 22.2.3.24
|
||||||
function TypedArraySome(f, receiver) {
|
function TypedArraySome(f, receiver) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ function TypedArraySome(f, receiver) {
|
|||||||
|
|
||||||
// ES6 section 22.2.3.27
|
// ES6 section 22.2.3.27
|
||||||
function TypedArrayToLocaleString() {
|
function TypedArrayToLocaleString() {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ function TypedArrayToString() {
|
|||||||
|
|
||||||
// ES6 section 22.2.3.14
|
// ES6 section 22.2.3.14
|
||||||
function TypedArrayJoin(separator) {
|
function TypedArrayJoin(separator) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
@ -292,7 +292,7 @@ function TypedArrayJoin(separator) {
|
|||||||
|
|
||||||
// ES6 draft 07-15-13, section 22.2.3.19
|
// ES6 draft 07-15-13, section 22.2.3.19
|
||||||
function TypedArrayReduce(callback, current) {
|
function TypedArrayReduce(callback, current) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
return InnerArrayReduce(callback, current, this, length,
|
return InnerArrayReduce(callback, current, this, length,
|
||||||
@ -303,7 +303,7 @@ function TypedArrayReduce(callback, current) {
|
|||||||
|
|
||||||
// ES6 draft 07-15-13, section 22.2.3.19
|
// ES6 draft 07-15-13, section 22.2.3.19
|
||||||
function TypedArrayReduceRight(callback, current) {
|
function TypedArrayReduceRight(callback, current) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
|
|
||||||
var length = %_TypedArrayGetLength(this);
|
var length = %_TypedArrayGetLength(this);
|
||||||
return InnerArrayReduceRight(callback, current, this, length,
|
return InnerArrayReduceRight(callback, current, this, length,
|
||||||
@ -313,7 +313,7 @@ function TypedArrayReduceRight(callback, current) {
|
|||||||
|
|
||||||
|
|
||||||
function TypedArraySlice(start, end) {
|
function TypedArraySlice(start, end) {
|
||||||
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
||||||
var len = %_TypedArrayGetLength(this);
|
var len = %_TypedArrayGetLength(this);
|
||||||
|
|
||||||
var relativeStart = TO_INTEGER(start);
|
var relativeStart = TO_INTEGER(start);
|
||||||
|
@ -11758,6 +11758,16 @@ void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HOptimizedGraphBuilder::GenerateIsTypedArray(CallRuntime* call) {
|
||||||
|
DCHECK(call->arguments()->length() == 1);
|
||||||
|
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
|
||||||
|
HValue* value = Pop();
|
||||||
|
HHasInstanceTypeAndBranch* result =
|
||||||
|
New<HHasInstanceTypeAndBranch>(value, JS_TYPED_ARRAY_TYPE);
|
||||||
|
return ast_context()->ReturnControl(result, call->id());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
|
void HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
|
||||||
DCHECK(call->arguments()->length() == 1);
|
DCHECK(call->arguments()->length() == 1);
|
||||||
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
|
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
|
||||||
|
@ -2171,6 +2171,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
|||||||
#define FOR_EACH_HYDROGEN_INTRINSIC(F) \
|
#define FOR_EACH_HYDROGEN_INTRINSIC(F) \
|
||||||
F(IsSmi) \
|
F(IsSmi) \
|
||||||
F(IsArray) \
|
F(IsArray) \
|
||||||
|
F(IsTypedArray) \
|
||||||
F(IsRegExp) \
|
F(IsRegExp) \
|
||||||
F(IsJSProxy) \
|
F(IsJSProxy) \
|
||||||
F(IsConstructCall) \
|
F(IsConstructCall) \
|
||||||
|
@ -3513,7 +3513,6 @@ void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
@ -3536,6 +3535,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(eax, if_false);
|
||||||
|
__ CmpObjectType(eax, JS_TYPED_ARRAY_TYPE, ebx);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(equal, if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -3627,6 +3627,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(v0, if_false);
|
||||||
|
__ GetObjectType(v0, a1, a1);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(eq, a1, Operand(JS_TYPED_ARRAY_TYPE), if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -3630,6 +3630,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(v0, if_false);
|
||||||
|
__ GetObjectType(v0, a1, a1);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(eq, a1, Operand(JS_TYPED_ARRAY_TYPE), if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -3656,6 +3656,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(r3, if_false);
|
||||||
|
__ CompareObjectType(r3, r4, r4, JS_TYPED_ARRAY_TYPE);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(eq, if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -339,7 +339,7 @@ function TypedArraySet(obj, offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function TypedArrayGetToStringTag() {
|
function TypedArrayGetToStringTag() {
|
||||||
if (!%IsTypedArray(this)) return;
|
if (!%_IsTypedArray(this)) return;
|
||||||
var name = %_ClassOf(this);
|
var name = %_ClassOf(this);
|
||||||
if (IS_UNDEFINED(name)) return;
|
if (IS_UNDEFINED(name)) return;
|
||||||
return name;
|
return name;
|
||||||
|
@ -3526,6 +3526,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(rax, if_false);
|
||||||
|
__ CmpObjectType(rax, JS_TYPED_ARRAY_TYPE, rbx);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(equal, if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -3504,7 +3504,6 @@ void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
@ -3527,6 +3526,28 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
|
||||||
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
|
DCHECK(args->length() == 1);
|
||||||
|
|
||||||
|
VisitForAccumulatorValue(args->at(0));
|
||||||
|
|
||||||
|
Label materialize_true, materialize_false;
|
||||||
|
Label* if_true = NULL;
|
||||||
|
Label* if_false = NULL;
|
||||||
|
Label* fall_through = NULL;
|
||||||
|
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||||
|
&if_false, &fall_through);
|
||||||
|
|
||||||
|
__ JumpIfSmi(eax, if_false);
|
||||||
|
__ CmpObjectType(eax, JS_TYPED_ARRAY_TYPE, ebx);
|
||||||
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
Split(equal, if_true, if_false, fall_through);
|
||||||
|
|
||||||
|
context()->Plug(if_true, if_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
DCHECK(args->length() == 1);
|
DCHECK(args->length() == 1);
|
||||||
|
@ -173,6 +173,37 @@ TEST_F(JSIntrinsicLoweringTest, InlineIsArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// %_IsTypedArray
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(JSIntrinsicLoweringTest, InlineIsTypedArray) {
|
||||||
|
Node* const input = Parameter(0);
|
||||||
|
Node* const context = Parameter(1);
|
||||||
|
Node* const effect = graph()->start();
|
||||||
|
Node* const control = graph()->start();
|
||||||
|
Reduction const r = Reduce(graph()->NewNode(
|
||||||
|
javascript()->CallRuntime(Runtime::kInlineIsTypedArray, 1), input,
|
||||||
|
context, effect, control));
|
||||||
|
ASSERT_TRUE(r.Changed());
|
||||||
|
|
||||||
|
Node* phi = r.replacement();
|
||||||
|
Capture<Node*> branch, if_false;
|
||||||
|
EXPECT_THAT(
|
||||||
|
phi,
|
||||||
|
IsPhi(
|
||||||
|
static_cast<MachineType>(kTypeBool | kRepTagged), IsFalseConstant(),
|
||||||
|
IsWord32Equal(IsLoadField(AccessBuilder::ForMapInstanceType(),
|
||||||
|
IsLoadField(AccessBuilder::ForMap(), input,
|
||||||
|
effect, CaptureEq(&if_false)),
|
||||||
|
effect, _),
|
||||||
|
IsInt32Constant(JS_TYPED_ARRAY_TYPE)),
|
||||||
|
IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
|
||||||
|
IsBranch(IsObjectIsSmi(input), control))),
|
||||||
|
AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// %_IsFunction
|
// %_IsFunction
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user