Reviewers: Sven Panne,
Description:
Allow loading constant function from proto chain.
This enables Crankshaft to use HConstant for loading constant functions
on the prototype chain when building a monomorphic load. This pattern
appears in several JavaScript frameworks.
[email protected]
TEST=mjsunit/compiler/proto-chain-constant
Please review this at https://chromiumcodereview.appspot.com/12052008/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/hydrogen.cc
A + test/mjsunit/compiler/proto-chain-constant.js
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
57ba4655e14b9d262a6b9e0e6b62a93fa70a9aba..e19a12e28ab2ed6259a693970f4967f669aabd90
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -6289,7 +6289,7 @@ HInstruction*
HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
return new(zone()) HConstant(function, Representation::Tagged());
}
- // Handle a load from a known field somewhere in the protoype chain.
+ // Handle a load from a known field somewhere in the prototype chain.
LookupInPrototypes(map, name, &lookup);
if (lookup.IsField()) {
Handle<JSObject> prototype(JSObject::cast(map->prototype()));
@@ -6301,6 +6301,17 @@ HInstruction*
HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
return BuildLoadNamedField(holder_value, holder_map, &lookup);
}
+ // Handle a load of a constant function somewhere in the prototype chain.
+ if (lookup.IsConstantFunction()) {
+ Handle<JSObject> prototype(JSObject::cast(map->prototype()));
+ Handle<JSObject> holder(lookup.holder());
+ Handle<Map> holder_map(holder->map());
+ AddCheckMapsWithTransitions(object, map);
+ AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder));
+ Handle<JSFunction>
function(lookup.GetConstantFunctionFromMap(*holder_map));
+ return new(zone()) HConstant(function, Representation::Tagged());
+ }
+
// No luck, do a generic load.
return BuildLoadNamedGeneric(object, name, expr);
}
Index: test/mjsunit/compiler/proto-chain-constant.js
diff --git a/test/mjsunit/compiler/proto-chain-load.js
b/test/mjsunit/compiler/proto-chain-constant.js
similarity index 63%
copy from test/mjsunit/compiler/proto-chain-load.js
copy to test/mjsunit/compiler/proto-chain-constant.js
index
60c6431d2b180f858abecef650b27ddb6a23f4e4..0d9e3b0e1e10b46737904db6c9b53c702ed9fa25
100644
--- a/test/mjsunit/compiler/proto-chain-load.js
+++ b/test/mjsunit/compiler/proto-chain-constant.js
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -27,18 +27,29 @@
// Flags: --allow-natives-syntax
-// Test HLoadNamedField on the proto chain.
+// Test loading a constant function on the prototype chain.
-var obj4 = Object.create(null, { f4: {value: 4} });
-var obj3 = Object.create(obj4, { f3: {value: 3} });
-var obj2 = Object.create(obj3, { f2: {value: 2} });
-var obj1 = Object.create(obj2, { f1: {value: 1} });
-var obj0 = Object.create(obj1, { f0: {value: 0} });
+var c = Object.create;
+var obj4 = c(null, { f4: { value: function() { return 4; }, writable: true
}});
+var obj3 = c(obj4, { f3: { value: function() { return 3; }, writable: true
}});
+var obj2 = c(obj3, { f2: { value: function() { return 2; }, writable: true
}});
+var obj1 = c(obj2, { f1: { value: function() { return 1; }, writable: true
}});
+var obj0 = c(obj1, { f0: { value: function() { return 0; }, writable: true
}});
function get4(obj) { return obj.f4; }
-assertEquals(4, get4(obj0));
-assertEquals(4, get4(obj0));
+assertEquals(4, get4(obj0)());
+assertEquals(4, get4(obj0)());
%OptimizeFunctionOnNextCall(get4);
-assertEquals(4, get4(obj0));
-assertEquals(4, get4(obj0));
+assertEquals(4, get4(obj0)());
+obj4.f4 = function() { return 5; };
+assertEquals(5, get4(obj0)());
+
+function get3(obj) { return obj.f3; }
+
+assertEquals(3, get3(obj0)());
+assertEquals(3, get3(obj0)());
+%OptimizeFunctionOnNextCall(get3);
+assertEquals(3, get3(obj0)());
+obj2.f3 = function() { return 6; };
+assertEquals(6, get3(obj0)());
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev