Author: [email protected]
Date: Tue Jun 30 07:07:29 2009
New Revision: 2308

Modified:
    branches/bleeding_edge/src/arm/stub-cache-arm.cc
    branches/bleeding_edge/src/disassembler.cc
    branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
    branches/bleeding_edge/src/ic.cc
    branches/bleeding_edge/src/stub-cache.cc
    branches/bleeding_edge/src/stub-cache.h
    branches/bleeding_edge/test/cctest/test-api.cc

Log:
Tweaks to global object inline cache code.

Remove the check for deleted properties in the global load inline cache if  
the property is known to be read only.

Propegate the in loop flag for the global call inline cache.

Changed the propagation of the code flags in the call stub compiler to  
compute these the same way for all types of call stubs and assert that the  
flags for the generated code is the same as those used for the cache lookup.

Addressed a few comments from previous review in test-api.cc.
Review URL: http://codereview.chromium.org/150101

Modified: branches/bleeding_edge/src/arm/stub-cache-arm.cc
==============================================================================
--- branches/bleeding_edge/src/arm/stub-cache-arm.cc    (original)
+++ branches/bleeding_edge/src/arm/stub-cache-arm.cc    Tue Jun 30 07:07:29  
2009
@@ -496,9 +496,7 @@
  Object* CallStubCompiler::CompileCallField(Object* object,
                                             JSObject* holder,
                                             int index,
-                                           String* name,
-                                           Code::Flags flags) {
-  ASSERT_EQ(FIELD, Code::ExtractTypeFromFlags(flags));
+                                           String* name) {
    // ----------- S t a t e -------------
    //  -- lr: return address
    // -----------------------------------
@@ -540,16 +538,14 @@
    __ Jump(ic, RelocInfo::CODE_TARGET);

    // Return the generated code.
-  return GetCodeWithFlags(flags, name);
+  return GetCode(FIELD, name);
  }


  Object* CallStubCompiler::CompileCallConstant(Object* object,
                                                JSObject* holder,
                                                JSFunction* function,
-                                              CheckType check,
-                                              Code::Flags flags) {
-  ASSERT_EQ(CONSTANT_FUNCTION, Code::ExtractTypeFromFlags(flags));
+                                              CheckType check) {
    // ----------- S t a t e -------------
    //  -- lr: return address
    // -----------------------------------
@@ -664,7 +660,7 @@
    if (function->shared()->name()->IsString()) {
      function_name = String::cast(function->shared()->name());
    }
-  return GetCodeWithFlags(flags, function_name);
+  return GetCode(CONSTANT_FUNCTION, function_name);
  }


@@ -1018,7 +1014,8 @@

  Object* LoadStubCompiler::CompileLoadGlobal(JSGlobalObject* object,
                                              JSGlobalPropertyCell* cell,
-                                            String* name) {
+                                            String* name,
+                                            bool is_dont_delete) {
    // ----------- S t a t e -------------
    //  -- r2    : name
    //  -- lr    : return address
@@ -1038,9 +1035,11 @@
    __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell)));
    __ ldr(r0, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));

-  // Check for deleted property.
-  __ cmp(r0, Operand(Factory::the_hole_value()));
-  __ b(eq, &miss);
+  // Check for deleted property if property can actually be deleted.
+  if (!is_dont_delete) {
+    __ cmp(r0, Operand(Factory::the_hole_value()));
+    __ b(eq, &miss);
+  }

    __ Ret();


Modified: branches/bleeding_edge/src/disassembler.cc
==============================================================================
--- branches/bleeding_edge/src/disassembler.cc  (original)
+++ branches/bleeding_edge/src/disassembler.cc  Tue Jun 30 07:07:29 2009
@@ -243,6 +243,9 @@
              PropertyType type = code->type();
              out.AddFormatted(", %s", Code::PropertyType2String(type));
            }
+          if (code->ic_in_loop() == IN_LOOP) {
+            out.AddFormatted(", in_loop");
+          }
            if (kind == Code::CALL_IC) {
              out.AddFormatted(", argc = %d", code->arguments_count());
            }

Modified: branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/stub-cache-ia32.cc  (original)
+++ branches/bleeding_edge/src/ia32/stub-cache-ia32.cc  Tue Jun 30 07:07:29  
2009
@@ -475,9 +475,7 @@
  Object* CallStubCompiler::CompileCallField(Object* object,
                                             JSObject* holder,
                                             int index,
-                                           String* name,
-                                           Code::Flags flags) {
-  ASSERT_EQ(FIELD, Code::ExtractTypeFromFlags(flags));
+                                           String* name) {
    // ----------- S t a t e -------------
    // -----------------------------------
    Label miss;
@@ -518,16 +516,14 @@
    __ jmp(ic, RelocInfo::CODE_TARGET);

    // Return the generated code.
-  return GetCodeWithFlags(flags, name);
+  return GetCode(FIELD, name);
  }


  Object* CallStubCompiler::CompileCallConstant(Object* object,
                                                JSObject* holder,
                                                JSFunction* function,
-                                              CheckType check,
-                                              Code::Flags flags) {
-  ASSERT_EQ(CONSTANT_FUNCTION, Code::ExtractTypeFromFlags(flags));
+                                              CheckType check) {
    // ----------- S t a t e -------------
    // -----------------------------------
    Label miss;
@@ -643,7 +639,7 @@
    if (function->shared()->name()->IsString()) {
      function_name = String::cast(function->shared()->name());
    }
-  return GetCodeWithFlags(flags, function_name);
+  return GetCode(CONSTANT_FUNCTION, function_name);
  }


@@ -1098,7 +1094,8 @@

  Object* LoadStubCompiler::CompileLoadGlobal(JSGlobalObject* object,
                                              JSGlobalPropertyCell* cell,
-                                            String* name) {
+                                            String* name,
+                                            bool is_dont_delete) {
    // ----------- S t a t e -------------
    //  -- ecx    : name
    //  -- esp[0] : return address
@@ -1118,9 +1115,11 @@
    __ mov(eax, Immediate(Handle<JSGlobalPropertyCell>(cell)));
    __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset));

-  // Check for deleted property.
-  __ cmp(eax, Factory::the_hole_value());
-  __ j(equal, &miss, not_taken);
+  // Check for deleted property if property can actually be deleted.
+  if (!is_dont_delete) {
+    __ cmp(eax, Factory::the_hole_value());
+    __ j(equal, &miss, not_taken);
+  }

    __ ret(0);


Modified: branches/bleeding_edge/src/ic.cc
==============================================================================
--- branches/bleeding_edge/src/ic.cc    (original)
+++ branches/bleeding_edge/src/ic.cc    Tue Jun 30 07:07:29 2009
@@ -632,7 +632,8 @@
            if (lookup->holder() != *global) return;
            JSGlobalPropertyCell* cell =
                JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
-          code = StubCache::ComputeLoadGlobal(*name, *global, cell);
+          code = StubCache::ComputeLoadGlobal(*name, *global,
+                                              cell,  
lookup->IsDontDelete());
          } else {
            // There is only one shared stub for loading normalized
            // properties. It does not traverse the prototype chain, so the

Modified: branches/bleeding_edge/src/stub-cache.cc
==============================================================================
--- branches/bleeding_edge/src/stub-cache.cc    (original)
+++ branches/bleeding_edge/src/stub-cache.cc    Tue Jun 30 07:07:29 2009
@@ -174,12 +174,13 @@

  Object* StubCache::ComputeLoadGlobal(String* name,
                                       JSGlobalObject* receiver,
-                                     JSGlobalPropertyCell* cell) {
+                                     JSGlobalPropertyCell* cell,
+                                     bool is_dont_delete) {
    Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
    Object* code = receiver->map()->FindInCodeCache(name, flags);
    if (code->IsUndefined()) {
      LoadStubCompiler compiler;
-    code = compiler.CompileLoadGlobal(receiver, cell, name);
+    code = compiler.CompileLoadGlobal(receiver, cell, name,  
is_dont_delete);
      if (code->IsFailure()) return code;
      LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
      Object* result = receiver->map()->UpdateCodeCache(name,  
Code::cast(code));
@@ -443,9 +444,10 @@
      // caches.
      if (!function->is_compiled()) return Failure::InternalError();
      // Compile the stub - only create stubs for fully compiled functions.
-    CallStubCompiler compiler(argc);
-    code = compiler.CompileCallConstant(object, holder, function, check,  
flags);
+    CallStubCompiler compiler(argc, in_loop);
+    code = compiler.CompileCallConstant(object, holder, function, check);
      if (code->IsFailure()) return code;
+    ASSERT_EQ(flags, Code::cast(code)->flags());
      LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
      Object* result = map->UpdateCodeCache(name, Code::cast(code));
      if (result->IsFailure()) return result;
@@ -476,9 +478,10 @@
                                                      argc);
    Object* code = map->FindInCodeCache(name, flags);
    if (code->IsUndefined()) {
-    CallStubCompiler compiler(argc);
-    code = compiler.CompileCallField(object, holder, index, name, flags);
+    CallStubCompiler compiler(argc, in_loop);
+    code = compiler.CompileCallField(object, holder, index, name);
      if (code->IsFailure()) return code;
+    ASSERT_EQ(flags, Code::cast(code)->flags());
      LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
      Object* result = map->UpdateCodeCache(name, Code::cast(code));
      if (result->IsFailure()) return result;
@@ -509,9 +512,10 @@
                                      argc);
    Object* code = map->FindInCodeCache(name, flags);
    if (code->IsUndefined()) {
-    CallStubCompiler compiler(argc);
+    CallStubCompiler compiler(argc, NOT_IN_LOOP);
      code = compiler.CompileCallInterceptor(object, holder, name);
      if (code->IsFailure()) return code;
+    ASSERT_EQ(flags, Code::cast(code)->flags());
      LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
      Object* result = map->UpdateCodeCache(name, Code::cast(code));
      if (result->IsFailure()) return result;
@@ -536,7 +540,8 @@
                                       JSGlobalObject* receiver,
                                       JSGlobalPropertyCell* cell,
                                       JSFunction* function) {
-  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, NORMAL);
+  Code::Flags flags =
+      Code::ComputeMonomorphicFlags(Code::CALL_IC, NORMAL, in_loop, argc);
    Object* code = receiver->map()->FindInCodeCache(name, flags);
    if (code->IsUndefined()) {
      // If the function hasn't been compiled yet, we cannot do it now
@@ -544,9 +549,10 @@
      // internal error which will make sure we do not update any
      // caches.
      if (!function->is_compiled()) return Failure::InternalError();
-    CallStubCompiler compiler(argc);
+    CallStubCompiler compiler(argc, in_loop);
      code = compiler.CompileCallGlobal(receiver, cell, function, name);
      if (code->IsFailure()) return code;
+    ASSERT_EQ(flags, Code::cast(code)->flags());
      LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
      Object* result = receiver->map()->UpdateCodeCache(name,  
Code::cast(code));
      if (result->IsFailure()) return code;
@@ -992,7 +998,7 @@
    int argc = arguments_.immediate();
    Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
                                                      type,
-                                                    NOT_IN_LOOP,
+                                                    in_loop_,
                                                      argc);
    return GetCodeWithFlags(flags, name);
  }

Modified: branches/bleeding_edge/src/stub-cache.h
==============================================================================
--- branches/bleeding_edge/src/stub-cache.h     (original)
+++ branches/bleeding_edge/src/stub-cache.h     Tue Jun 30 07:07:29 2009
@@ -80,7 +80,8 @@

    static Object* ComputeLoadGlobal(String* name,
                                     JSGlobalObject* receiver,
-                                   JSGlobalPropertyCell* cell);
+                                   JSGlobalPropertyCell* cell,
+                                   bool is_dont_delete);


    // ---
@@ -434,7 +435,8 @@

    Object* CompileLoadGlobal(JSGlobalObject* object,
                              JSGlobalPropertyCell* holder,
-                            String* name);
+                            String* name,
+                            bool is_dont_delete);

   private:
    Object* GetCode(PropertyType type, String* name);
@@ -501,18 +503,17 @@

  class CallStubCompiler: public StubCompiler {
   public:
-  explicit CallStubCompiler(int argc) : arguments_(argc) { }
+  explicit CallStubCompiler(int argc, InLoopFlag in_loop)
+      : arguments_(argc), in_loop_(in_loop) { }

    Object* CompileCallField(Object* object,
                             JSObject* holder,
                             int index,
-                           String* name,
-                           Code::Flags flags);
+                           String* name);
    Object* CompileCallConstant(Object* object,
                                JSObject* holder,
                                JSFunction* function,
-                              CheckType check,
-                              Code::Flags flags);
+                              CheckType check);
    Object* CompileCallInterceptor(Object* object,
                                   JSObject* holder,
                                   String* name);
@@ -523,6 +524,7 @@

   private:
    const ParameterCount arguments_;
+  const InLoopFlag in_loop_;

    const ParameterCount& arguments() { return arguments_; }


Modified: branches/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-api.cc      (original)
+++ branches/bleeding_edge/test/cctest/test-api.cc      Tue Jun 30 07:07:29 2009
@@ -6149,16 +6149,16 @@

    // Call f1 one time and f2 a number of times. This will ensure that f1  
still
    // uses the runtime system to retreive property a whereas f2 uses global  
load
-  // inline cache is used.
-  CHECK(!f1->Call(global, 0, NULL)->IsUndefined());
+  // inline cache.
+  CHECK(f1->Call(global, 0, NULL)->Equals(v8_num(1)));
    for (int i = 0; i < 4; i++) {
-    CHECK(!f2->Call(global, 0, NULL)->IsUndefined());
+    CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1)));
    }

    // Same for g1 and g2.
-  CHECK(!g1->Call(global, 0, NULL)->IsUndefined());
+  CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1)));
    for (int i = 0; i < 4; i++) {
-    CHECK(!g2->Call(global, 0, NULL)->IsUndefined());
+    CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1)));
    }

    // Detach the global and turn on access check.

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to