Revision: 24636
Author: [email protected]
Date: Wed Oct 15 13:26:43 2014 UTC
Log: Implement inline %_IsJSProxy() for full codegen and Hydrogen
Saving a runtime call for many builtin functions.
[email protected]
Review URL: https://codereview.chromium.org/651223002
https://code.google.com/p/v8/source/detail?r=24636
Modified:
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm64/full-codegen-arm64.cc
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/object-observe.js
/branches/bleeding_edge/src/runtime/runtime-proxy.cc
/branches/bleeding_edge/src/runtime/runtime.h
/branches/bleeding_edge/src/v8natives.js
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Oct 13 12:46:46
2014 UTC
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Oct 15 13:26:43
2014 UTC
@@ -3440,6 +3440,32 @@
}
+void FullCodeGenerator::EmitIsJSProxy(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);
+ Register map = r1;
+ Register type_reg = r2;
+ __ ldr(map, FieldMemOperand(r0, HeapObject::kMapOffset));
+ __ ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
+ __ sub(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+ __ cmp(type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE));
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+ Split(ls, if_true, if_false, fall_through);
+
+ context()->Plug(if_true, if_false);
+}
+
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);
=======================================
--- /branches/bleeding_edge/src/arm64/full-codegen-arm64.cc Mon Oct 13
12:46:46 2014 UTC
+++ /branches/bleeding_edge/src/arm64/full-codegen-arm64.cc Wed Oct 15
13:26:43 2014 UTC
@@ -3117,6 +3117,32 @@
}
+void FullCodeGenerator::EmitIsJSProxy(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);
+ Register map = x10;
+ Register type_reg = x11;
+ __ Ldr(map, FieldMemOperand(x0, HeapObject::kMapOffset));
+ __ Ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
+ __ Sub(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+ __ Cmp(type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE));
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+ Split(ls, if_true, if_false, fall_through);
+
+ context()->Plug(if_true, if_false);
+}
+
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Wed Oct 15 12:22:15 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Oct 15 13:26:43 2014 UTC
@@ -11536,6 +11536,29 @@
HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value);
return ast_context()->ReturnControl(result, call->id());
}
+
+
+void HOptimizedGraphBuilder::GenerateIsJSProxy(CallRuntime* call) {
+ DCHECK(call->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ HValue* value = Pop();
+ HIfContinuation continuation;
+ IfBuilder if_proxy(this);
+
+ HValue* smicheck = if_proxy.IfNot<HIsSmiAndBranch>(value);
+ if_proxy.And();
+ HValue* map = Add<HLoadNamedField>(value, smicheck,
HObjectAccess::ForMap());
+ HValue* instance_type = Add<HLoadNamedField>(
+ map, static_cast<HValue*>(NULL),
HObjectAccess::ForMapInstanceType());
+ if_proxy.If<HCompareNumericAndBranch>(
+ instance_type, Add<HConstant>(FIRST_JS_PROXY_TYPE), Token::GTE);
+ if_proxy.And();
+ if_proxy.If<HCompareNumericAndBranch>(
+ instance_type, Add<HConstant>(LAST_JS_PROXY_TYPE), Token::LTE);
+
+ if_proxy.CaptureContinuation(&continuation);
+ return ast_context()->ReturnContinuation(&continuation, call->id());
+}
void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Oct 13
12:46:46 2014 UTC
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Wed Oct 15
13:26:43 2014 UTC
@@ -3338,6 +3338,31 @@
}
+void FullCodeGenerator::EmitIsJSProxy(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);
+ Register map = ebx;
+ __ mov(map, FieldOperand(eax, HeapObject::kMapOffset));
+ __ CmpInstanceType(map, FIRST_JS_PROXY_TYPE);
+ __ j(less, if_false);
+ __ CmpInstanceType(map, LAST_JS_PROXY_TYPE);
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+ Split(less_equal, if_true, if_false, fall_through);
+
+ context()->Plug(if_true, if_false);
+}
+
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);
=======================================
--- /branches/bleeding_edge/src/object-observe.js Mon Jul 14 14:05:30 2014
UTC
+++ /branches/bleeding_edge/src/object-observe.js Wed Oct 15 13:26:43 2014
UTC
@@ -194,9 +194,9 @@
function ObjectInfoGetOrCreate(object) {
var objectInfo = ObjectInfoGet(object);
if (IS_UNDEFINED(objectInfo)) {
- if (!%IsJSProxy(object))
+ if (!%_IsJSProxy(object)) {
%SetIsObserved(object);
-
+ }
objectInfo = {
object: object,
changeObservers: null,
=======================================
--- /branches/bleeding_edge/src/runtime/runtime-proxy.cc Tue Sep 30
10:46:04 2014 UTC
+++ /branches/bleeding_edge/src/runtime/runtime-proxy.cc Wed Oct 15
13:26:43 2014 UTC
@@ -35,10 +35,10 @@
}
-RUNTIME_FUNCTION(Runtime_IsJSProxy) {
+RUNTIME_FUNCTION(RuntimeReference_IsJSProxy) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSProxy());
}
=======================================
--- /branches/bleeding_edge/src/runtime/runtime.h Thu Oct 9 11:36:22 2014
UTC
+++ /branches/bleeding_edge/src/runtime/runtime.h Wed Oct 15 13:26:43 2014
UTC
@@ -291,7 +291,6 @@
/* Harmony proxies */ \
F(CreateJSProxy, 2, 1) \
F(CreateJSFunctionProxy, 4, 1) \
- F(IsJSProxy, 1, 1) \
F(IsJSFunctionProxy, 1, 1) \
F(GetHandler, 1, 1) \
F(GetCallTrap, 1, 1) \
@@ -668,6 +667,7 @@
F(IsNonNegativeSmi, 1, 1) \
F(IsArray, 1, 1) \
F(IsRegExp, 1, 1) \
+ F(IsJSProxy, 1, 1) \
F(IsConstructCall, 0, 1) \
F(CallFunction, -1 /* receiver + n args + function */, 1) \
F(ArgumentsLength, 0, 1) \
=======================================
--- /branches/bleeding_edge/src/v8natives.js Tue Oct 14 09:59:24 2014 UTC
+++ /branches/bleeding_edge/src/v8natives.js Wed Oct 15 13:26:43 2014 UTC
@@ -238,7 +238,7 @@
// ECMA-262 - 15.2.4.5
function ObjectHasOwnProperty(V) {
- if (%IsJSProxy(this)) {
+ if (%_IsJSProxy(this)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(V)) return false;
@@ -260,7 +260,7 @@
// ECMA-262 - 15.2.4.6
function ObjectPropertyIsEnumerable(V) {
var P = ToName(V);
- if (%IsJSProxy(this)) {
+ if (%_IsJSProxy(this)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(V)) return false;
@@ -326,7 +326,7 @@
function ObjectKeys(obj) {
obj = ToObject(obj);
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
var handler = %GetHandler(obj);
var names = CallTrap0(handler, "keys", DerivedKeysTrap);
return ToNameArray(names, "keys", false);
@@ -623,7 +623,7 @@
// ES5 section 8.12.1.
function GetOwnPropertyJS(obj, v) {
var p = ToName(v);
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(v)) return UNDEFINED;
@@ -963,7 +963,7 @@
// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
function DefineOwnProperty(obj, p, desc, should_throw) {
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(p)) return false;
@@ -1111,7 +1111,7 @@
throw MakeTypeError("called_on_non_object",
["Object.getOwnPropertyNames"]);
}
// Special handling for proxies.
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
var handler = %GetHandler(obj);
var names = CallTrap0(handler, "getOwnPropertyNames", UNDEFINED);
return ToNameArray(names, "getOwnPropertyNames", false);
@@ -1139,7 +1139,7 @@
throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]);
}
var name = ToName(p);
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
// Clone the attributes object for protection.
// TODO(rossberg): not spec'ed yet, so not sure if this should involve
// non-own properties as it does (or non-enumerable ones, as it
doesn't?).
@@ -1248,7 +1248,7 @@
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.seal"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
ProxyFix(obj);
}
var names = ObjectGetOwnPropertyNames(obj);
@@ -1270,7 +1270,7 @@
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.freeze"]);
}
- var isProxy = %IsJSProxy(obj);
+ var isProxy = %_IsJSProxy(obj);
if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
if (isProxy) {
ProxyFix(obj);
@@ -1300,7 +1300,7 @@
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object",
["Object.preventExtension"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
ProxyFix(obj);
}
%PreventExtensions(obj);
@@ -1313,7 +1313,7 @@
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.isSealed"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
return false;
}
if (%IsExtensible(obj)) {
@@ -1336,7 +1336,7 @@
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
return false;
}
if (%IsExtensible(obj)) {
@@ -1358,7 +1358,7 @@
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.isExtensible"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
return true;
}
return %IsExtensible(obj);
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Mon Oct 13 12:46:46
2014 UTC
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Wed Oct 15 13:26:43
2014 UTC
@@ -3330,6 +3330,31 @@
}
+void FullCodeGenerator::EmitIsJSProxy(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);
+ Register map = rbx;
+ __ movp(map, FieldOperand(rax, HeapObject::kMapOffset));
+ __ CmpInstanceType(map, FIRST_JS_PROXY_TYPE);
+ __ j(less, if_false);
+ __ CmpInstanceType(map, LAST_JS_PROXY_TYPE);
+ PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+ Split(less_equal, if_true, if_false, fall_through);
+
+ context()->Plug(if_true, if_false);
+}
+
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
DCHECK(expr->arguments()->length() == 0);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.