Inline simple getter calls.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 30 Jul 2012 10:42:21 +0000 (10:42 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 30 Jul 2012 10:42:21 +0000 (10:42 +0000)
Currently only simple getter calls are handled (i.e. no calls in count
operations or compound assignments), and deoptimization in the getter is not
handled at all. Because of the latter, we temporarily hide this feature behind a
new flag --inline-accessors, which is false by default.

Review URL: https://chromiumcodereview.appspot.com/10828066

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12223 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/full-codegen-arm.cc
src/ast.h
src/flag-definitions.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/x64/full-codegen-x64.cc

index d2325f7..9bac93d 100644 (file)
@@ -2275,6 +2275,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
   if (key->IsPropertyName()) {
     VisitForAccumulatorValue(expr->obj());
     EmitNamedPropertyLoad(expr);
+    PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
     context()->Plug(r0);
   } else {
     VisitForStackValue(expr->obj());
index 8c9606a..63ee29a 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1513,6 +1513,9 @@ class Property: public Expression {
   Expression* key() const { return key_; }
   virtual int position() const { return pos_; }
 
+  // Bailout support.
+  int ReturnId() const { return return_id_; }
+
   bool IsStringLength() const { return is_string_length_; }
   bool IsStringAccess() const { return is_string_access_; }
   bool IsFunctionPrototype() const { return is_function_prototype_; }
@@ -1535,6 +1538,7 @@ class Property: public Expression {
         obj_(obj),
         key_(key),
         pos_(pos),
+        return_id_(GetNextId(isolate)),
         is_monomorphic_(false),
         is_uninitialized_(false),
         is_array_length_(false),
@@ -1546,6 +1550,7 @@ class Property: public Expression {
   Expression* obj_;
   Expression* key_;
   int pos_;
+  const int return_id_;
 
   SmallMapList receiver_types_;
   bool is_monomorphic_ : 1;
index 51918a5..19d7d37 100644 (file)
@@ -213,6 +213,7 @@ DEFINE_bool(cache_optimized_code, true,
             "cache optimized code for closures")
 DEFINE_bool(inline_construct, true, "inline constructor calls")
 DEFINE_bool(inline_arguments, true, "inline functions with arguments object")
+DEFINE_bool(inline_accessors, false, "inline JavaScript accessors")
 DEFINE_int(loop_weight, 1, "loop weight for representation inference")
 
 DEFINE_bool(optimize_for_in, true,
index f614850..73c9173 100644 (file)
@@ -6352,7 +6352,11 @@ void HGraphBuilder::VisitProperty(Property* expr) {
       Handle<AccessorPair> accessors;
       Handle<JSObject> holder;
       if (LookupAccessorPair(map, name, &accessors, &holder)) {
-        instr = BuildCallGetter(Pop(), map, accessors, holder);
+        AddCheckConstantFunction(holder, Top(), map, true);
+        Handle<JSFunction> getter(JSFunction::cast(accessors->getter()));
+        if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
+        AddInstruction(new(zone()) HPushArgument(Pop()));
+        instr = new(zone()) HCallConstantFunction(getter, 1);
       } else {
         instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
       }
@@ -6920,6 +6924,18 @@ bool HGraphBuilder::TryInlineConstruct(CallNew* expr, HValue* receiver) {
 }
 
 
+bool HGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
+                                    Property* prop) {
+  return TryInline(CALL_AS_METHOD,
+                   getter,
+                   0,
+                   NULL,
+                   prop->id(),
+                   prop->ReturnId(),
+                   NORMAL_RETURN);
+}
+
+
 bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) {
   if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
   BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
index 3cdd7f8..61d792f 100644 (file)
@@ -1040,6 +1040,7 @@ class HGraphBuilder: public AstVisitor {
 
   bool TryInlineCall(Call* expr, bool drop_extra = false);
   bool TryInlineConstruct(CallNew* expr, HValue* receiver);
+  bool TryInlineGetter(Handle<JSFunction> getter, Property* prop);
   bool TryInlineBuiltinMethodCall(Call* expr,
                                   HValue* receiver,
                                   Handle<Map> receiver_map,
index 75253c0..ceee56a 100644 (file)
@@ -2214,6 +2214,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
     VisitForAccumulatorValue(expr->obj());
     __ mov(edx, result_register());
     EmitNamedPropertyLoad(expr);
+    PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
     context()->Plug(eax);
   } else {
     VisitForStackValue(expr->obj());
index 4a19d6c..a5e7dcf 100644 (file)
@@ -2299,6 +2299,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
   if (key->IsPropertyName()) {
     VisitForAccumulatorValue(expr->obj());
     EmitNamedPropertyLoad(expr);
+    PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
     context()->Plug(v0);
   } else {
     VisitForStackValue(expr->obj());
index 344905e..702ee29 100644 (file)
@@ -2188,6 +2188,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
   if (key->IsPropertyName()) {
     VisitForAccumulatorValue(expr->obj());
     EmitNamedPropertyLoad(expr);
+    PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
     context()->Plug(rax);
   } else {
     VisitForStackValue(expr->obj());