Revision: 7287
Author:   [email protected]
Date:     Mon Mar 21 07:22:33 2011
Log:      [Arguments] Remove the arguments shadow symbol.

The only essential use remaining was to detect an allocated arguments object
to avoid OSR.  The shared function info now has a flag indicating that there
might be an allocated arguments object so we can avoid OSR for those
functions.

[email protected]

Review URL: http://codereview.chromium.org/6685119
http://code.google.com/p/v8/source/detail?r=7287

Modified:
 /branches/experimental/arguments/src/compiler.cc
 /branches/experimental/arguments/src/contexts.cc
 /branches/experimental/arguments/src/heap-profiler.h
 /branches/experimental/arguments/src/heap.h
 /branches/experimental/arguments/src/ia32/full-codegen-ia32.cc
 /branches/experimental/arguments/src/objects-inl.h
 /branches/experimental/arguments/src/objects.h
 /branches/experimental/arguments/src/runtime-profiler.cc
 /branches/experimental/arguments/src/runtime.cc
 /branches/experimental/arguments/src/scopeinfo.h

=======================================
--- /branches/experimental/arguments/src/compiler.cc Tue Mar 15 07:26:55 2011 +++ /branches/experimental/arguments/src/compiler.cc Mon Mar 21 07:22:33 2011
@@ -768,6 +768,7 @@
   function_info->set_try_full_codegen(lit->try_full_codegen());
   function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   function_info->set_strict_mode(lit->strict_mode());
+  function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
 }


=======================================
--- /branches/experimental/arguments/src/contexts.cc Tue Dec 7 03:31:57 2010 +++ /branches/experimental/arguments/src/contexts.cc Mon Mar 21 07:22:33 2011
@@ -74,8 +74,10 @@
 }


-Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, - int* index_, PropertyAttributes* attributes) {
+Handle<Object> Context::Lookup(Handle<String> name,
+                               ContextLookupFlags flags,
+                               int* index_,
+                               PropertyAttributes* attributes) {
   Handle<Context> context(this);

   bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0;
@@ -95,7 +97,7 @@
       PrintF("\n");
     }

-    // check extension/with object
+    // Check the context extension object.
     if (context->has_extension()) {
       Handle<JSObject> extension = Handle<JSObject>(context->extension());
       // Context extension objects needs to behave as if they have no
@@ -108,7 +110,6 @@
         *attributes = extension->GetPropertyAttribute(*name);
       }
       if (*attributes != ABSENT) {
-        // property found
         if (FLAG_trace_contexts) {
           PrintF("=> found property in context object %p\n",
                  reinterpret_cast<void*>(*extension));
@@ -118,16 +119,13 @@
     }

     if (context->is_function_context()) {
-      // we have context-local slots
-
-      // check non-parameter locals in context
+      // We may have context-local slots.  Check locals in the context.
       Handle<SerializedScopeInfo> scope_info(
           context->closure()->shared()->scope_info());
       Variable::Mode mode;
       int index = scope_info->ContextSlotIndex(*name, &mode);
       ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS);
       if (index >= 0) {
-        // slot found
         if (FLAG_trace_contexts) {
           PrintF("=> found local in context slot %d (mode = %d)\n",
                  index, mode);
@@ -140,39 +138,28 @@
// declared variables that were introduced through declaration nodes)
         // must not appear here.
         switch (mode) {
-          case Variable::INTERNAL:  // fall through
-          case Variable::VAR: *attributes = NONE; break;
-          case Variable::CONST: *attributes = READ_ONLY; break;
-          case Variable::DYNAMIC: UNREACHABLE(); break;
-          case Variable::DYNAMIC_GLOBAL: UNREACHABLE(); break;
-          case Variable::DYNAMIC_LOCAL: UNREACHABLE(); break;
-          case Variable::TEMPORARY: UNREACHABLE(); break;
+          case Variable::INTERNAL:  // Fall through.
+          case Variable::VAR:
+            *attributes = NONE;
+            break;
+          case Variable::CONST:
+            *attributes = READ_ONLY;
+            break;
+          case Variable::DYNAMIC:
+          case Variable::DYNAMIC_GLOBAL:
+          case Variable::DYNAMIC_LOCAL:
+          case Variable::TEMPORARY:
+            UNREACHABLE();
+            break;
         }
         return context;
       }

-      // check parameter locals in context
-      int param_index = scope_info->ParameterIndex(*name);
-      if (param_index >= 0) {
-        // slot found.
-        int index =
- scope_info->ContextSlotIndex(Heap::arguments_shadow_symbol(), NULL); - ASSERT(index >= 0); // arguments must exist and be in the heap context
-        Handle<JSObject> arguments(JSObject::cast(context->get(index)));
-        ASSERT(arguments->HasLocalProperty(Heap::length_symbol()));
-        if (FLAG_trace_contexts) {
- PrintF("=> found parameter %d in arguments object\n", param_index);
-        }
-        *index_ = param_index;
-        *attributes = NONE;
-        return arguments;
-      }
-
- // check intermediate context (holding only the function name variable)
+      // Check the slot corresponding to the intermediate context holding
+      // only the function name variable.
       if (follow_context_chain) {
         int index = scope_info->FunctionContextSlotIndex(*name);
         if (index >= 0) {
-          // slot found
           if (FLAG_trace_contexts) {
             PrintF("=> found intermediate function in context slot %d\n",
                    index);
@@ -184,7 +171,7 @@
       }
     }

-    // proceed with enclosing context
+    // Proceed with the enclosing context.
     if (context->IsGlobalContext()) {
       follow_context_chain = false;
     } else if (context->is_function_context()) {
@@ -194,7 +181,6 @@
     }
   } while (follow_context_chain);

-  // slot not found
   if (FLAG_trace_contexts) {
     PrintF("=> no property/slot found\n");
   }
=======================================
--- /branches/experimental/arguments/src/heap-profiler.h Thu Mar 10 04:05:31 2011 +++ /branches/experimental/arguments/src/heap-profiler.h Mon Mar 21 07:22:33 2011
@@ -155,9 +155,9 @@
     // Their actual value is irrelevant for us.
     switch (special) {
       case ROOTS: return Heap::result_symbol();
-      case GLOBAL_PROPERTY: return Heap::code_symbol();
-      case CODE: return Heap::arguments_shadow_symbol();
-      case SELF: return Heap::catch_var_symbol();
+      case GLOBAL_PROPERTY: return Heap::catch_var_symbol();
+      case CODE: return Heap::code_symbol();
+      case SELF: return Heap::this_symbol();
       default:
         UNREACHABLE();
         return NULL;
=======================================
--- /branches/experimental/arguments/src/heap.h Thu Mar 10 04:05:31 2011
+++ /branches/experimental/arguments/src/heap.h Mon Mar 21 07:22:33 2011
@@ -131,7 +131,6 @@
   V(StringImpl_symbol, "StringImpl")                                     \
   V(arguments_symbol, "arguments")                                       \
   V(Arguments_symbol, "Arguments")                                       \
-  V(arguments_shadow_symbol, ".arguments")                               \
   V(call_symbol, "call")                                                 \
   V(apply_symbol, "apply")                                               \
   V(caller_symbol, "caller")                                             \
=======================================
--- /branches/experimental/arguments/src/ia32/full-codegen-ia32.cc Mon Mar 21 01:24:41 2011 +++ /branches/experimental/arguments/src/ia32/full-codegen-ia32.cc Mon Mar 21 07:22:33 2011
@@ -1135,7 +1135,7 @@
   // Three cases: non-this global variables, lookup slots, and all other
   // types of slots.
   Slot* slot = var->AsSlot();
-  ASSERT((var->is_global() && !var->is_this()) == (slot != NULL));
+  ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));

   if (slot == NULL) {
     Comment cmnt(masm_, "Global variable");
=======================================
--- /branches/experimental/arguments/src/objects-inl.h Thu Mar 10 04:05:31 2011 +++ /branches/experimental/arguments/src/objects-inl.h Mon Mar 21 07:22:33 2011
@@ -2889,7 +2889,8 @@
                kIsExpressionBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
                kIsTopLevelBit)
-BOOL_GETTER(SharedFunctionInfo, compiler_hints,
+BOOL_GETTER(SharedFunctionInfo,
+            compiler_hints,
             has_only_simple_this_property_assignments,
             kHasOnlySimpleThisPropertyAssignments)
 BOOL_ACCESSORS(SharedFunctionInfo,
@@ -2900,6 +2901,10 @@
                compiler_hints,
                allows_lazy_compilation,
                kAllowLazyCompilation)
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               uses_arguments,
+               kUsesArguments)


 #if V8_HOST_ARCH_32_BIT
@@ -2983,18 +2988,10 @@
 }


-bool SharedFunctionInfo::live_objects_may_exist() {
-  return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
-}
-
-
-void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
-  if (value) {
-    set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
-  } else {
-    set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
-  }
-}
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               live_objects_may_exist,
+               kLiveObjectsMayExist)


 bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
@@ -3002,9 +2999,10 @@
 }


-bool SharedFunctionInfo::optimization_disabled() {
-  return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
-}
+BOOL_GETTER(SharedFunctionInfo,
+            compiler_hints,
+            optimization_disabled,
+            kOptimizationDisabled)


 void SharedFunctionInfo::set_optimization_disabled(bool disable) {
@@ -3019,16 +3017,10 @@
 }


-bool SharedFunctionInfo::strict_mode() {
-  return BooleanBit::get(compiler_hints(), kStrictModeFunction);
-}
-
-
-void SharedFunctionInfo::set_strict_mode(bool value) {
-  set_compiler_hints(BooleanBit::set(compiler_hints(),
-                                     kStrictModeFunction,
-                                     value));
-}
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               strict_mode,
+               kStrictModeFunction)


 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
=======================================
--- /branches/experimental/arguments/src/objects.h      Thu Mar 10 04:05:31 2011
+++ /branches/experimental/arguments/src/objects.h      Mon Mar 21 07:22:33 2011
@@ -4111,9 +4111,7 @@
// False if there are definitely no live objects created from this function.
   // True if live objects _may_ exist (existence not guaranteed).
   // May go back from true to false after GC.
-  inline bool live_objects_may_exist();
-
-  inline void set_live_objects_may_exist(bool value);
+  DECL_BOOLEAN_ACCESSORS(live_objects_may_exist)

   // [instance class name]: class name for instances.
   DECL_ACCESSORS(instance_class_name, Object)
@@ -4201,14 +4199,12 @@
   // this.x = y; where y is either a constant or refers to an argument.
   inline bool has_only_simple_this_property_assignments();

-  inline bool try_full_codegen();
-  inline void set_try_full_codegen(bool flag);
+  DECL_BOOLEAN_ACCESSORS(try_full_codegen)

   // Indicates if this function can be lazy compiled.
   // This is used to determine if we can safely flush code from a function
   // when doing GC if we expect that the function will no longer be used.
-  inline bool allows_lazy_compilation();
-  inline void set_allows_lazy_compilation(bool flag);
+  DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)

   // Indicates how many full GCs this function has survived with assigned
   // code object. Used to determine when it is relatively safe to flush
@@ -4222,12 +4218,13 @@
   // shared function info. If a function is repeatedly optimized or if
   // we cannot optimize the function we disable optimization to avoid
   // spending time attempting to optimize it again.
-  inline bool optimization_disabled();
-  inline void set_optimization_disabled(bool value);
+  DECL_BOOLEAN_ACCESSORS(optimization_disabled)

   // Indicates whether the function is a strict mode function.
-  inline bool strict_mode();
-  inline void set_strict_mode(bool value);
+  DECL_BOOLEAN_ACCESSORS(strict_mode)
+
+ // False if the function definitely does not allocate an arguments object.
+  DECL_BOOLEAN_ACCESSORS(uses_arguments)

   // Indicates whether or not the code in the shared function support
   // deoptimization.
@@ -4410,6 +4407,7 @@
   static const int kCodeAgeMask = 0x7;
   static const int kOptimizationDisabled = 7;
   static const int kStrictModeFunction = 8;
+  static const int kUsesArguments = 9;

  private:
 #if V8_HOST_ARCH_32_BIT
=======================================
--- /branches/experimental/arguments/src/runtime-profiler.cc Wed Mar 2 02:16:47 2011 +++ /branches/experimental/arguments/src/runtime-profiler.cc Mon Mar 21 07:22:33 2011
@@ -169,7 +169,7 @@
   // We are not prepared to do OSR for a function that already has an
   // allocated arguments object.  The optimized code would bypass it for
   // arguments accesses, which is unsound.  Don't try OSR.
-  if (shared->scope_info()->HasArgumentsShadow()) return;
+  if (shared->uses_arguments()) return;

   // We're using on-stack replacement: patch the unoptimized code so that
   // any back edge in any unoptimized frame will trigger on-stack
=======================================
--- /branches/experimental/arguments/src/runtime.cc     Tue Mar 15 11:20:10 2011
+++ /branches/experimental/arguments/src/runtime.cc     Mon Mar 21 07:22:33 2011
@@ -7201,7 +7201,7 @@
   CONVERT_ARG_CHECKED(JSFunction, function, 0);

   // We're not prepared to handle a function with arguments object.
-  ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
+  ASSERT(!function->shared()->uses_arguments());

// We have hit a back edge in an unoptimized frame for a function that was
   // selected for on-stack replacement.  Find the unoptimized code object.
@@ -9370,16 +9370,13 @@
     int context_index = serialized_scope_info->ContextSlotIndex(
         *scope_info.context_slot_name(i), NULL);

-    // Don't include the arguments shadow (.arguments) context variable.
- if (*scope_info.context_slot_name(i) != Heap::arguments_shadow_symbol()) {
-      RETURN_IF_EMPTY_HANDLE_VALUE(
-          SetProperty(scope_object,
-                      scope_info.context_slot_name(i),
-                      Handle<Object>(context->get(context_index)),
-                      NONE,
-                      kNonStrictMode),
-          false);
-    }
+    RETURN_IF_EMPTY_HANDLE_VALUE(
+        SetProperty(scope_object,
+                    scope_info.context_slot_name(i),
+                    Handle<Object>(context->get(context_index)),
+                    NONE,
+                    kNonStrictMode),
+        false);
   }

   return true;
@@ -9465,28 +9462,6 @@
// Allocate and initialize a JSObject with all the content of theis function
   // closure.
Handle<JSObject> closure_scope = Factory::NewJSObject(Top::object_function());
-
-  // Check whether the arguments shadow object exists.
-  int arguments_shadow_index =
- shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(),
-                                             NULL);
-  if (arguments_shadow_index >= 0) {
-    // In this case all the arguments are available in the arguments shadow
-    // object.
-    Handle<JSObject> arguments_shadow(
-        JSObject::cast(context->get(arguments_shadow_index)));
-    for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
- // We don't expect exception-throwing getters on the arguments shadow. - Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
-      RETURN_IF_EMPTY_HANDLE_VALUE(
-          SetProperty(closure_scope,
-                      scope_info.parameter_name(i),
-                      Handle<Object>(element),
-                      NONE,
-                      kNonStrictMode),
-          Handle<JSObject>());
-    }
-  }

   // Fill all context locals to the context extension.
   if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
=======================================
--- /branches/experimental/arguments/src/scopeinfo.h Tue Dec 7 03:31:57 2010 +++ /branches/experimental/arguments/src/scopeinfo.h Mon Mar 21 07:22:33 2011
@@ -111,11 +111,6 @@

   // Does this scope call eval?
   bool CallsEval();
-
-  // Does this scope have an arguments shadow?
-  bool HasArgumentsShadow() {
-    return StackSlotIndex(Heap::arguments_shadow_symbol()) >= 0;
-  }

   // Return the number of stack slots for code.
   int NumberOfStackSlots();

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

Reply via email to