Revision: 23287
Author:   [email protected]
Date:     Fri Aug 22 00:04:38 2014 UTC
Log:      Version 3.29.14 (based on bleeding_edge revision r23268)

Don't inline Array.shift() if receiver map is not extensible (Chromium issue 405517).

Performance and stability improvements on all platforms.
https://code.google.com/p/v8/source/detail?r=23287

Added:
 /trunk/test/mjsunit/regress/regress-crbug-405517.js
Modified:
 /trunk/ChangeLog
 /trunk/src/bootstrapper.cc
 /trunk/src/elements.cc
 /trunk/src/heap/spaces-inl.h
 /trunk/src/heap/spaces.cc
 /trunk/src/heap-snapshot-generator.cc
 /trunk/src/hydrogen-instructions.cc
 /trunk/src/hydrogen-instructions.h
 /trunk/src/hydrogen.cc
 /trunk/src/hydrogen.h
 /trunk/src/ic.cc
 /trunk/src/lookup-inl.h
 /trunk/src/lookup.cc
 /trunk/src/lookup.h
 /trunk/src/mirror-debugger.js
 /trunk/src/msan.h
 /trunk/src/objects-printer.cc
 /trunk/src/objects.cc
 /trunk/src/parser.cc
 /trunk/src/parser.h
 /trunk/src/preparser.cc
 /trunk/src/preparser.h
 /trunk/src/property-details.h
 /trunk/src/property.cc
 /trunk/src/property.h
 /trunk/src/runtime.cc
 /trunk/src/version.cc
 /trunk/test/cctest/cctest.status
 /trunk/test/cctest/test-api.cc
 /trunk/test/mjsunit/es6/array-iterator.js
 /trunk/tools/run-tests.py

=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-crbug-405517.js Fri Aug 22 00:04:38 2014 UTC
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --gc-interval=203
+
+function f() {
+ var e = [0];
+ %PreventExtensions(e);
+ for (var i = 0; i < 4; i++) e.shift();
+}
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
=======================================
--- /trunk/ChangeLog    Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/ChangeLog    Fri Aug 22 00:04:38 2014 UTC
@@ -1,3 +1,11 @@
+2014-08-22: Version 3.29.14
+
+ Don't inline Array.shift() if receiver map is not extensible (Chromium
+        issue 405517).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-08-21: Version 3.29.11

         Refactor ParseObjectLiteral.
=======================================
--- /trunk/src/bootstrapper.cc  Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/bootstrapper.cc  Fri Aug 22 00:04:38 2014 UTC
@@ -2464,7 +2464,6 @@
           // Do not occur since the from object has fast properties.
         case HANDLER:
         case INTERCEPTOR:
-        case NONEXISTENT:
// No element in instance descriptors have proxy or interceptor type.
           UNREACHABLE();
           break;
=======================================
--- /trunk/src/elements.cc      Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/elements.cc      Fri Aug 22 00:04:38 2014 UTC
@@ -1364,7 +1364,7 @@
           uint32_t number = static_cast<uint32_t>(key->Number());
           if (new_length <= number && number < old_length) {
             PropertyDetails details = dict->DetailsAt(i);
-            if (details.IsDontDelete()) new_length = number + 1;
+            if (!details.IsConfigurable()) new_length = number + 1;
           }
         }
       }
=======================================
--- /trunk/src/heap/spaces-inl.h        Wed Aug  6 00:06:29 2014 UTC
+++ /trunk/src/heap/spaces-inl.h        Fri Aug 22 00:04:38 2014 UTC
@@ -8,6 +8,7 @@
 #include "src/heap/spaces.h"
 #include "src/heap-profiler.h"
 #include "src/isolate.h"
+#include "src/msan.h"
 #include "src/v8memory.h"

 namespace v8 {
@@ -258,6 +259,7 @@
     if (identity() == CODE_SPACE) {
       SkipList::Update(object->address(), size_in_bytes);
     }
+    MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes);
     return object;
   }

@@ -280,6 +282,9 @@
   allocation_info_.set_top(allocation_info_.top() + size_in_bytes);
   DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);

+ // The slow path above ultimately goes through AllocateRaw, so this suffices.
+  MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes);
+
   return obj;
 }

=======================================
--- /trunk/src/heap/spaces.cc   Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/heap/spaces.cc   Fri Aug 22 00:04:38 2014 UTC
@@ -2881,6 +2881,8 @@

   HeapObject* object = page->GetObject();

+  MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), object_size);
+
   if (Heap::ShouldZapGarbage()) {
// Make the object consistent so the heap can be verified in OldSpaceStep.
     // We only need to do this in debug builds or if verify_heap is on.
=======================================
--- /trunk/src/heap-snapshot-generator.cc       Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/heap-snapshot-generator.cc       Fri Aug 22 00:04:38 2014 UTC
@@ -1700,9 +1700,6 @@
         case HANDLER:  // only in lookup results, not in descriptors
         case INTERCEPTOR:  // only in lookup results, not in descriptors
           break;
-        case NONEXISTENT:
-          UNREACHABLE();
-          break;
       }
     }
   } else {
=======================================
--- /trunk/src/hydrogen-instructions.cc Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/hydrogen-instructions.cc Fri Aug 22 00:04:38 2014 UTC
@@ -3584,14 +3584,14 @@

 OStream& HLoadGlobalCell::PrintDataTo(OStream& os) const {  // NOLINT
   os << "[" << *cell().handle() << "]";
-  if (!details_.IsDontDelete()) os << " (deleteable)";
+  if (details_.IsConfigurable()) os << " (configurable)";
   if (details_.IsReadOnly()) os << " (read-only)";
   return os;
 }


 bool HLoadGlobalCell::RequiresHoleCheck() const {
-  if (details_.IsDontDelete() && !details_.IsReadOnly()) return false;
+  if (!details_.IsConfigurable()) return false;
   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     HValue* use = it.value();
     if (!use->IsChange()) return true;
@@ -3613,7 +3613,7 @@

 OStream& HStoreGlobalCell::PrintDataTo(OStream& os) const {  // NOLINT
   os << "[" << *cell().handle() << "] = " << NameOf(value());
-  if (!details_.IsDontDelete()) os << " (deleteable)";
+  if (details_.IsConfigurable()) os << " (configurable)";
   if (details_.IsReadOnly()) os << " (read-only)";
   return os;
 }
=======================================
--- /trunk/src/hydrogen-instructions.h  Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/hydrogen-instructions.h  Fri Aug 22 00:04:38 2014 UTC
@@ -5793,9 +5793,7 @@
                                  Handle<PropertyCell>, PropertyDetails);

   Unique<PropertyCell> cell() const { return cell_; }
-  bool RequiresHoleCheck() {
-    return !details_.IsDontDelete() || details_.IsReadOnly();
-  }
+  bool RequiresHoleCheck() { return details_.IsConfigurable(); }
   bool NeedsWriteBarrier() {
     return StoringValueNeedsWriteBarrier(value());
   }
=======================================
--- /trunk/src/hydrogen.cc      Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/hydrogen.cc      Fri Aug 22 00:04:38 2014 UTC
@@ -5602,7 +5602,7 @@
               PropertyAccessInfo info(this, STORE, ToType(map), name);
               if (info.CanAccessMonomorphic()) {
                 HValue* checked_literal = Add<HCheckMaps>(literal, map);
-                DCHECK(!info.lookup()->IsPropertyCallbacks());
+                DCHECK(!info.IsAccessor());
                 store = BuildMonomorphicAccess(
                     &info, literal, checked_literal, value,
                     BailoutId::None(), BailoutId::None());
@@ -5789,9 +5789,8 @@
     PropertyAccessInfo* info,
     HValue* checked_object) {
   // See if this is a load for an immutable property
-  if (checked_object->ActualValue()->IsConstant() &&
-      info->lookup()->IsCacheable() &&
-      info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) {
+  if (checked_object->ActualValue()->IsConstant() && info->IsCacheable() &&
+      info->IsReadOnly() && !info->IsConfigurable()) {
     Handle<Object> object(
         HConstant::cast(checked_object->ActualValue())->handle(isolate()));

@@ -5831,7 +5830,7 @@
     PropertyAccessInfo* info,
     HValue* checked_object,
     HValue* value) {
-  bool transition_to_field = info->lookup()->IsTransition();
+  bool transition_to_field = info->IsTransition();
   // TODO(verwaest): Move this logic into PropertyAccessInfo.
   HObjectAccess field_access = info->access();

@@ -5908,26 +5907,26 @@

   if (!LookupDescriptor()) return false;

-  if (!lookup_.IsFound()) {
-    return (!info->lookup_.IsFound() || info->has_holder()) &&
-        map()->prototype() == info->map()->prototype();
+  if (!IsFound()) {
+    return (!info->IsFound() || info->has_holder()) &&
+           map()->prototype() == info->map()->prototype();
   }

   // Mismatch if the other access info found the property in the prototype
   // chain.
   if (info->has_holder()) return false;

-  if (lookup_.IsPropertyCallbacks()) {
+  if (IsAccessor()) {
     return accessor_.is_identical_to(info->accessor_) &&
         api_holder_.is_identical_to(info->api_holder_);
   }

-  if (lookup_.IsConstant()) {
+  if (IsConstant()) {
     return constant_.is_identical_to(info->constant_);
   }

-  DCHECK(lookup_.IsField());
-  if (!info->lookup_.IsField()) return false;
+  DCHECK(IsField());
+  if (!info->IsField()) return false;

   Representation r = access_.representation();
   if (IsLoad()) {
@@ -5970,25 +5969,23 @@


bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
-  if (!IsLoad() && lookup_.IsProperty() &&
-      (lookup_.IsReadOnly() || !lookup_.IsCacheable())) {
+  if (!IsLoad() && IsProperty() && (IsReadOnly() || !IsCacheable())) {
     return false;
   }

-  if (lookup_.IsField()) {
+  if (IsField()) {
     // Construct the object field access.
-    int index = lookup_.GetLocalFieldIndexFromMap(*map);
-    Representation representation = lookup_.representation();
-    access_ = HObjectAccess::ForField(map, index, representation, name_);
+    int index = GetLocalFieldIndexFromMap(map);
+    access_ = HObjectAccess::ForField(map, index, representation(), name_);

     // Load field map for heap objects.
     LoadFieldMaps(map);
-  } else if (lookup_.IsPropertyCallbacks()) {
-    Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate());
-    if (!callback->IsAccessorPair()) return false;
-    Object* raw_accessor = IsLoad()
-        ? Handle<AccessorPair>::cast(callback)->getter()
-        : Handle<AccessorPair>::cast(callback)->setter();
+  } else if (IsAccessor()) {
+    Handle<Object> accessors = GetAccessorsFromMap(map);
+    if (!accessors->IsAccessorPair()) return false;
+    Object* raw_accessor =
+        IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter()
+                 : Handle<AccessorPair>::cast(accessors)->setter();
     if (!raw_accessor->IsJSFunction()) return false;
     Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
     if (accessor->shared()->IsApiFunction()) {
@@ -6001,8 +5998,8 @@
       }
     }
     accessor_ = accessor;
-  } else if (lookup_.IsConstant()) {
-    constant_ = handle(lookup_.GetConstantFromMap(*map), isolate());
+  } else if (IsConstant()) {
+    constant_ = GetConstantFromMap(map);
   }

   return true;
@@ -6016,7 +6013,7 @@
   field_type_ = HType::Tagged();

   // Figure out the field type from the accessor map.
- Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate());
+  Handle<HeapType> field_type = GetFieldTypeFromMap(map);

   // Collect the (stable) maps from the field type.
   int num_field_maps = field_type->NumClasses();
@@ -6041,9 +6038,8 @@
   DCHECK(field_type_.IsHeapObject());

   // Add dependency on the map that introduced the field.
-  Map::AddDependentCompilationInfo(
-      handle(lookup_.GetFieldOwnerFromMap(*map), isolate()),
-      DependentCode::kFieldTypeGroup, top_info());
+  Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map),
+ DependentCode::kFieldTypeGroup, top_info());
 }


@@ -6061,7 +6057,7 @@
       return false;
     }
     map->LookupDescriptor(*holder_, *name_, &lookup_);
-    if (lookup_.IsFound()) return LoadResult(map);
+    if (IsFound()) return LoadResult(map);
   }
   lookup_.NotFound();
   return true;
@@ -6077,14 +6073,14 @@
     return IsLoad();
   }
   if (!LookupDescriptor()) return false;
-  if (lookup_.IsFound()) {
+  if (IsFound()) {
     if (IsLoad()) return true;
-    return !lookup_.IsReadOnly() && lookup_.IsCacheable();
+    return !IsReadOnly() && IsCacheable();
   }
   if (!LookupInPrototypes()) return false;
   if (IsLoad()) return true;

-  if (lookup_.IsPropertyCallbacks()) return true;
+  if (IsAccessor()) return true;
   Handle<Map> map = this->map();
   map->LookupTransition(NULL, *name_, &lookup_);
   if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) {
@@ -6131,8 +6127,8 @@
   if (type_->Is(Type::Number())) return false;

   // Multiple maps cannot transition to the same target map.
-  DCHECK(!IsLoad() || !lookup_.IsTransition());
-  if (lookup_.IsTransition() && types->length() > 1) return false;
+  DCHECK(!IsLoad() || !IsTransition());
+  if (IsTransition() && types->length() > 1) return false;

   for (int i = 1; i < types->length(); ++i) {
     PropertyAccessInfo test_info(
@@ -6186,12 +6182,12 @@
     checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
   }

-  if (!info->lookup()->IsFound()) {
+  if (!info->IsFound()) {
     DCHECK(info->IsLoad());
     return graph()->GetConstantUndefined();
   }

-  if (info->lookup()->IsField()) {
+  if (info->IsField()) {
     if (info->IsLoad()) {
       return BuildLoadNamedField(info, checked_holder);
     } else {
@@ -6199,12 +6195,12 @@
     }
   }

-  if (info->lookup()->IsTransition()) {
+  if (info->IsTransition()) {
     DCHECK(!info->IsLoad());
     return BuildStoreNamedField(info, checked_object, value);
   }

-  if (info->lookup()->IsPropertyCallbacks()) {
+  if (info->IsAccessor()) {
     Push(checked_object);
     int argument_count = 1;
     if (!info->IsLoad()) {
@@ -6228,7 +6224,7 @@
     return BuildCallConstantFunction(info->accessor(), argument_count);
   }

-  DCHECK(info->lookup()->IsConstant());
+  DCHECK(info->IsConstant());
   if (info->IsLoad()) {
     return New<HConstant>(info->constant());
   } else {
@@ -7484,8 +7480,7 @@
        i < types->length() && ordered_functions < kMaxCallPolymorphism;
        ++i) {
     PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
-    if (info.CanAccessMonomorphic() &&
-        info.lookup()->IsConstant() &&
+    if (info.CanAccessMonomorphic() && info.IsConstant() &&
         info.constant()->IsJSFunction()) {
       if (info.type()->Is(Type::String())) {
         if (handled_string) continue;
@@ -8343,7 +8338,7 @@
       ElementsKind kind = receiver_map->elements_kind();
       if (!IsFastElementsKind(kind)) return false;
       if (receiver_map->is_observed()) return false;
-      DCHECK(receiver_map->is_extensible());
+      if (!receiver_map->is_extensible()) return false;

// If there may be elements accessors in the prototype chain, the fast
       // inlined version can't be used.
=======================================
--- /trunk/src/hydrogen.h       Thu Aug 21 00:04:56 2014 UTC
+++ /trunk/src/hydrogen.h       Fri Aug 22 00:04:38 2014 UTC
@@ -2495,7 +2495,6 @@
     bool has_holder() { return !holder_.is_null(); }
     bool IsLoad() const { return access_type_ == LOAD; }

-    LookupResult* lookup() { return &lookup_; }
     Handle<JSObject> holder() { return holder_; }
     Handle<JSFunction> accessor() { return accessor_; }
     Handle<Object> constant() { return constant_; }
@@ -2503,11 +2502,39 @@
     SmallMapList* field_maps() { return &field_maps_; }
     HType field_type() const { return field_type_; }
     HObjectAccess access() { return access_; }
+
+    bool IsFound() const { return lookup_.IsFound(); }
+    bool IsProperty() const { return lookup_.IsProperty(); }
+    bool IsField() const { return lookup_.IsField(); }
+    bool IsConstant() const { return lookup_.IsConstant(); }
+    bool IsAccessor() const { return lookup_.IsPropertyCallbacks(); }
+    bool IsTransition() const { return lookup_.IsTransition(); }
+
+    bool IsConfigurable() const { return lookup_.IsConfigurable(); }
+    bool IsReadOnly() const { return lookup_.IsReadOnly(); }
+    bool IsCacheable() const { return lookup_.IsCacheable(); }

    private:
+    Handle<Object> GetAccessorsFromMap(Handle<Map> map) const {
+      return handle(lookup_.GetValueFromMap(*map), isolate());
+    }
+    Handle<Object> GetConstantFromMap(Handle<Map> map) const {
+      return handle(lookup_.GetConstantFromMap(*map), isolate());
+    }
+    Handle<HeapType> GetFieldTypeFromMap(Handle<Map> map) const {
+      return handle(lookup_.GetFieldTypeFromMap(*map), isolate());
+    }
+    Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const {
+      return handle(lookup_.GetFieldOwnerFromMap(*map));
+    }
+    int GetLocalFieldIndexFromMap(Handle<Map> map) const {
+      return lookup_.GetLocalFieldIndexFromMap(*map);
+    }
+ Representation representation() const { return lookup_.representation(); }
+
     Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
     Zone* zone() { return builder_->zone(); }
-    Isolate* isolate() { return lookup_.isolate(); }
+    Isolate* isolate() const { return lookup_.isolate(); }
     CompilationInfo* top_info() { return builder_->top_info(); }
     CompilationInfo* current_info() { return builder_->current_info(); }

=======================================
--- /trunk/src/ic.cc    Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/ic.cc    Fri Aug 22 00:04:38 2014 UTC
@@ -1597,7 +1597,6 @@
       }
       case CONSTANT:
         break;
-      case NONEXISTENT:
       case HANDLER:
         UNREACHABLE();
         break;
=======================================
--- /trunk/src/lookup-inl.h     Thu Aug 21 00:04:56 2014 UTC
+++ /trunk/src/lookup-inl.h     Fri Aug 22 00:04:38 2014 UTC
@@ -20,7 +20,10 @@
          next->map()->is_hidden_prototype());

   if (!check_derived() &&
-      !(check_hidden() && next->map()->is_hidden_prototype())) {
+      !(check_hidden() && next->map()->is_hidden_prototype()) &&
+ // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even
+      // when not checking other hidden prototypes.
+      !(map->IsJSGlobalProxyMap() && next->IsJSGlobalObject())) {
     return NULL;
   }

=======================================
--- /trunk/src/lookup.cc        Thu Aug 21 00:04:56 2014 UTC
+++ /trunk/src/lookup.cc        Fri Aug 22 00:04:38 2014 UTC
@@ -100,7 +100,6 @@
       property_kind_ = ACCESSOR;
       break;
     case v8::internal::HANDLER:
-    case v8::internal::NONEXISTENT:
     case v8::internal::INTERCEPTOR:
       UNREACHABLE();
   }
=======================================
--- /trunk/src/lookup.h Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/lookup.h Fri Aug 22 00:04:38 2014 UTC
@@ -70,7 +70,7 @@
         state_(NOT_FOUND),
         property_kind_(DATA),
         property_encoding_(DESCRIPTOR),
-        property_details_(NONE, NONEXISTENT, Representation::None()),
+        property_details_(NONE, NORMAL, Representation::None()),
         isolate_(name->GetIsolate()),
         name_(name),
         maybe_receiver_(receiver),
@@ -88,7 +88,7 @@
         state_(NOT_FOUND),
         property_kind_(DATA),
         property_encoding_(DESCRIPTOR),
-        property_details_(NONE, NONEXISTENT, Representation::None()),
+        property_details_(NONE, NORMAL, Representation::None()),
         isolate_(name->GetIsolate()),
         name_(name),
         holder_map_(holder->map()),
@@ -153,7 +153,7 @@
     DCHECK(has_property_);
     return property_details_;
   }
- bool IsConfigurable() const { return !property_details().IsDontDelete(); } + bool IsConfigurable() const { return property_details().IsConfigurable(); }
   bool IsReadOnly() const { return property_details().IsReadOnly(); }
   Representation representation() const {
     return property_details().representation();
=======================================
--- /trunk/src/mirror-debugger.js       Fri Aug  8 15:46:17 2014 UTC
+++ /trunk/src/mirror-debugger.js       Fri Aug 22 00:04:38 2014 UTC
@@ -179,7 +179,6 @@
 PropertyType.Callbacks               = 3;
 PropertyType.Handler                 = 4;
 PropertyType.Interceptor             = 5;
-PropertyType.Nonexistent             = 6;


 // Different attributes for a property.
=======================================
--- /trunk/src/msan.h   Wed Jun  4 00:06:13 2014 UTC
+++ /trunk/src/msan.h   Fri Aug 22 00:04:38 2014 UTC
@@ -17,8 +17,17 @@
 # define MEMORY_SANITIZER
 #endif

+#if defined(MEMORY_SANITIZER)
+# include <sanitizer/msan_interface.h>  // NOLINT
+
+// Marks a memory range as uninitialized, as if it was allocated here.
+# define MSAN_ALLOCATED_UNINITIALIZED_MEMORY(p, s) \
+    __msan_allocated_memory((p), (s))
+#else
+# define MSAN_ALLOCATED_UNINITIALIZED_MEMORY(p, s)
+#endif
+
 #if defined(MEMORY_SANITIZER) && !defined(USE_SIMULATOR)
-# include <sanitizer/msan_interface.h>  // NOLINT
 // Marks a memory range as fully initialized.
 # define MSAN_MEMORY_IS_INITIALIZED_IN_JIT(p, s) __msan_unpoison((p), (s))
 #else
=======================================
--- /trunk/src/objects-printer.cc       Wed Aug 20 00:06:26 2014 UTC
+++ /trunk/src/objects-printer.cc       Fri Aug 22 00:04:38 2014 UTC
@@ -242,8 +242,6 @@
         case NORMAL:  // only in slow mode
         case HANDLER:  // only in lookup results, not in descriptors
         case INTERCEPTOR:  // only in lookup results, not in descriptors
-        // There are no transitions in the descriptor array.
-        case NONEXISTENT:
           UNREACHABLE();
           break;
       }
@@ -377,7 +375,6 @@
         case NORMAL:
         case HANDLER:
         case INTERCEPTOR:
-        case NONEXISTENT:
           UNREACHABLE();
           break;
       }
@@ -1107,7 +1104,6 @@
       case NORMAL:
       case HANDLER:
       case INTERCEPTOR:
-      case NONEXISTENT:
         UNREACHABLE();
         break;
     }
=======================================
--- /trunk/src/objects.cc       Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/objects.cc       Fri Aug 22 00:04:38 2014 UTC
@@ -709,11 +709,11 @@
     // If we have a global object set the cell to the hole.
     if (object->IsGlobalObject()) {
       PropertyDetails details = dictionary->DetailsAt(entry);
-      if (details.IsDontDelete()) {
+      if (!details.IsConfigurable()) {
if (mode != FORCE_DELETION) return isolate->factory()->false_value();
         // When forced to delete global properties, we have to make a
         // map change to invalidate any ICs that think they can load
-        // from the DontDelete cell without checking if it contains
+        // from the non-configurable cell without checking if it contains
         // the hole value.
Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
         DCHECK(new_map->is_dictionary_map());
@@ -2774,7 +2774,6 @@
       case NORMAL:
       case HANDLER:
       case INTERCEPTOR:
-      case NONEXISTENT:
         UNREACHABLE();
     }
   }
@@ -4264,7 +4263,6 @@
         break;
       case HANDLER:
       case NORMAL:
-      case NONEXISTENT:
         UNREACHABLE();
         break;
     }
@@ -6010,7 +6008,7 @@
     Object* result = dictionary->ValueAt(entry);
     PropertyDetails details = dictionary->DetailsAt(entry);
     if (details.type() == CALLBACKS && result->IsAccessorPair()) {
-      DCHECK(!details.IsDontDelete());
+      DCHECK(details.IsConfigurable());
       if (details.attributes() != attributes) {
         dictionary->DetailsAtPut(
             entry,
@@ -6823,7 +6821,6 @@
     case NORMAL:
     case INTERCEPTOR:
     case HANDLER:
-    case NONEXISTENT:
       break;
   }

@@ -12947,11 +12944,11 @@
   uint32_t length = 0;
   CHECK(array->length()->ToArrayIndex(&length));
   if (length <= index) {
-    Isolate* isolate = array->GetIsolate();
-    LookupResult lookup(isolate);
-    Handle<Name> length_string = isolate->factory()->length_string();
-    array->LookupOwnRealNamedProperty(length_string, &lookup);
-    return lookup.IsReadOnly();
+ LookupIterator it(array, array->GetIsolate()->factory()->length_string(),
+                      LookupIterator::CHECK_PROPERTY);
+    CHECK(it.IsFound());
+    CHECK(it.HasProperty());
+    return it.IsReadOnly();
   }
   return false;
 }
@@ -13335,20 +13332,10 @@

 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
                                            Handle<Name> key) {
-  Isolate* isolate = object->GetIsolate();
-  SealHandleScope shs(isolate);
-  // Check access rights if needed.
-  if (object->IsAccessCheckNeeded()) {
-    if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
-      isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
-      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
-      return maybe(false);
-    }
-  }
-
-  LookupResult result(isolate);
-  object->LookupOwnRealNamedProperty(key, &result);
-  return maybe(result.IsFound() && !result.IsInterceptor());
+  LookupIterator it(object, key, LookupIterator::CHECK_ACCESS_CHECK);
+  Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
+  if (!maybe_result.has_value) return Maybe<bool>();
+  return maybe(it.IsFound());
 }


@@ -13383,20 +13370,10 @@

 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
                                                    Handle<Name> key) {
-  Isolate* isolate = object->GetIsolate();
-  SealHandleScope shs(isolate);
-  // Check access rights if needed.
-  if (object->IsAccessCheckNeeded()) {
-    if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
-      isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
-      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
-      return maybe(false);
-    }
-  }
-
-  LookupResult result(isolate);
-  object->LookupOwnRealNamedProperty(key, &result);
-  return maybe(result.IsPropertyCallbacks());
+  LookupIterator it(object, key, LookupIterator::CHECK_ACCESS_CHECK);
+  Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
+  if (!maybe_result.has_value) return Maybe<bool>();
+ return maybe(it.IsFound() && it.property_kind() == LookupIterator::ACCESSOR);
 }


@@ -15144,7 +15121,7 @@
   Factory* factory = dictionary->GetIsolate()->factory();
   PropertyDetails details = dictionary->DetailsAt(entry);
   // Ignore attributes if forcing a deletion.
-  if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) {
+  if (!details.IsConfigurable() && mode != JSReceiver::FORCE_DELETION) {
     return factory->false_value();
   }

=======================================
--- /trunk/src/parser.cc        Thu Aug 21 00:04:56 2014 UTC
+++ /trunk/src/parser.cc        Fri Aug 22 00:04:38 2014 UTC
@@ -341,6 +341,26 @@
// ----------------------------------------------------------------------------
 // Implementation of Parser

+class ParserTraits::Checkpoint
+    : public ParserBase<ParserTraits>::CheckpointBase {
+ public:
+  explicit Checkpoint(ParserBase<ParserTraits>* parser)
+      : CheckpointBase(parser) {
+    isolate_ = parser->zone()->isolate();
+    saved_ast_node_id_ = isolate_->ast_node_id();
+  }
+
+  void Restore() {
+    CheckpointBase::Restore();
+    isolate_->set_ast_node_id(saved_ast_node_id_);
+  }
+
+ private:
+  Isolate* isolate_;
+  int saved_ast_node_id_;
+};
+
+
bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
   return identifier == parser_->ast_value_factory_->eval_string() ||
          identifier == parser_->ast_value_factory_->arguments_string();
=======================================
--- /trunk/src/parser.h Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/parser.h Fri Aug 22 00:04:38 2014 UTC
@@ -355,21 +355,6 @@
     typedef Variable GeneratorVariable;
     typedef v8::internal::Zone Zone;

-    class Checkpoint BASE_EMBEDDED {
-     public:
-      template <typename Parser>
-      explicit Checkpoint(Parser* parser) {
-        isolate_ = parser->zone()->isolate();
-        saved_ast_node_id_ = isolate_->ast_node_id();
-      }
-
-      void Restore() { isolate_->set_ast_node_id(saved_ast_node_id_); }
-
-     private:
-      Isolate* isolate_;
-      int saved_ast_node_id_;
-    };
-
     typedef v8::internal::AstProperties AstProperties;
     typedef Vector<VariableProxy*> ParameterIdentifierVector;

@@ -388,6 +373,8 @@
     typedef AstNodeFactory<AstConstructionVisitor> Factory;
   };

+  class Checkpoint;
+
   explicit ParserTraits(Parser* parser) : parser_(parser) {}

// Custom operations executed when FunctionStates are created and destructed.
=======================================
--- /trunk/src/preparser.cc     Fri Aug  8 15:46:17 2014 UTC
+++ /trunk/src/preparser.cc     Fri Aug 22 00:04:38 2014 UTC
@@ -32,6 +32,12 @@
 namespace v8 {
 namespace internal {

+class PreParserTraits::Checkpoint
+    : public ParserBase<PreParserTraits>::CheckpointBase {
+ public:
+  explicit Checkpoint(ParserBase<PreParserTraits>* parser)
+      : ParserBase<PreParserTraits>::CheckpointBase(parser) {}
+};

 void PreParserTraits::ReportMessageAt(Scanner::Location location,
                                       const char* message,
=======================================
--- /trunk/src/preparser.h      Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/preparser.h      Fri Aug 22 00:04:38 2014 UTC
@@ -117,7 +117,7 @@
   }

  protected:
-  friend class Traits::Type::Checkpoint;
+  friend class Traits::Checkpoint;

   enum AllowEvalOrArgumentsAsIdentifier {
     kAllowEvalOrArguments,
@@ -129,7 +129,7 @@
     PARSE_EAGERLY
   };

-  class ParserCheckpoint;
+  class CheckpointBase;

// --------------------------------------------------------------------------- // FunctionState and BlockState together implement the parser's scope stack.
@@ -226,18 +226,16 @@
     typename Traits::Type::Factory factory_;

     friend class ParserTraits;
-    friend class ParserCheckpoint;
+    friend class CheckpointBase;
   };

// Annoyingly, arrow functions first parse as comma expressions, then when we // see the => we have to go back and reinterpret the arguments as being formal // parameters. To do so we need to reset some of the parser state back to
   // what it was before the arguments were first seen.
-  class ParserCheckpoint : public Traits::Type::Checkpoint {
+  class CheckpointBase BASE_EMBEDDED {
    public:
-    template <typename Parser>
-    explicit ParserCheckpoint(Parser* parser)
-        : Traits::Type::Checkpoint(parser) {
+    explicit CheckpointBase(ParserBase* parser) {
       function_state_ = parser->function_state_;
       next_materialized_literal_index_ =
           function_state_->next_materialized_literal_index_;
@@ -246,7 +244,6 @@
     }

     void Restore() {
-      Traits::Type::Checkpoint::Restore();
       function_state_->next_materialized_literal_index_ =
           next_materialized_literal_index_;
       function_state_->next_handler_index_ = next_handler_index_;
@@ -1024,13 +1021,6 @@
     typedef PreParserScope Scope;
     typedef PreParserScope ScopePtr;

-    class Checkpoint BASE_EMBEDDED {
-     public:
-      template <typename Parser>
-      explicit Checkpoint(Parser* parser) {}
-      void Restore() {}
-    };
-
     // PreParser doesn't need to store generator variables.
     typedef void GeneratorVariable;
     // No interaction with Zones.
@@ -1054,6 +1044,8 @@
     typedef PreParserFactory Factory;
   };

+  class Checkpoint;
+
explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}

   // Custom operations executed when FunctionStates are created and
@@ -1979,7 +1971,7 @@
   }

   if (fni_ != NULL) fni_->Enter();
-  ParserCheckpoint checkpoint(this);
+  typename Traits::Checkpoint checkpoint(this);
   ExpressionT expression =
       this->ParseConditionalExpression(accept_IN, CHECK_OK);

=======================================
--- /trunk/src/property-details.h       Tue Aug  5 00:05:55 2014 UTC
+++ /trunk/src/property-details.h       Fri Aug 22 00:04:38 2014 UTC
@@ -46,16 +46,14 @@
 // A copy of this is in mirror-debugger.js.
 enum PropertyType {
   // Only in slow mode.
-  NORMAL                    = 0,
+  NORMAL = 0,
   // Only in fast mode.
-  FIELD                     = 1,
-  CONSTANT                  = 2,
-  CALLBACKS                 = 3,
+  FIELD = 1,
+  CONSTANT = 2,
+  CALLBACKS = 3,
   // Only in lookup results, not in descriptors.
-  HANDLER                   = 4,
-  INTERCEPTOR               = 5,
-  // Only used as a marker in LookupResult.
-  NONEXISTENT               = 6
+  HANDLER = 4,
+  INTERCEPTOR = 5
 };


@@ -262,7 +260,7 @@
   }

   bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
-  bool IsDontDelete() const { return (attributes() & DONT_DELETE) != 0; }
+  bool IsConfigurable() const { return (attributes() & DONT_DELETE) == 0; }
   bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
   bool IsDeleted() const { return DeletedField::decode(value_) != 0;}

=======================================
--- /trunk/src/property.cc      Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/property.cc      Fri Aug 22 00:04:38 2014 UTC
@@ -47,9 +47,6 @@
       return os << " -type = lookup proxy\n";
     case INTERCEPTOR:
       return os << " -type = lookup interceptor\n";
-    case NONEXISTENT:
-      UNREACHABLE();
-      break;
   }
   return os;
 }
=======================================
--- /trunk/src/property.h       Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/property.h       Fri Aug 22 00:04:38 2014 UTC
@@ -120,7 +120,7 @@
         holder_(NULL),
         transition_(NULL),
         cacheable_(true),
-        details_(NONE, NONEXISTENT, Representation::None()) {
+        details_(NONE, NORMAL, Representation::None()) {
     isolate->set_top_lookup_result(this);
   }

@@ -158,8 +158,6 @@
       case HANDLER:
       case INTERCEPTOR:
         return true;
-      case NONEXISTENT:
-        UNREACHABLE();
     }
     UNREACHABLE();
     return true;
@@ -198,7 +196,7 @@

   void NotFound() {
     lookup_type_ = NOT_FOUND;
-    details_ = PropertyDetails(NONE, NONEXISTENT, Representation::None());
+    details_ = PropertyDetails(NONE, NORMAL, Representation::None());
     holder_ = NULL;
     transition_ = NULL;
   }
@@ -220,13 +218,11 @@

   Representation representation() const {
     DCHECK(IsFound());
-    DCHECK(details_.type() != NONEXISTENT);
     return details_.representation();
   }

   PropertyAttributes GetAttributes() const {
     DCHECK(IsFound());
-    DCHECK(details_.type() != NONEXISTENT);
     return details_.attributes();
   }

@@ -247,7 +243,6 @@

   bool IsReadOnly() const {
     DCHECK(IsFound());
-    DCHECK(details_.type() != NONEXISTENT);
     return details_.IsReadOnly();
   }

@@ -257,8 +252,7 @@
   }

   bool IsNormal() const {
-    DCHECK(!(details_.type() == NORMAL && !IsFound()));
-    return IsDescriptorOrDictionary() && type() == NORMAL;
+    return IsFound() && IsDescriptorOrDictionary() && type() == NORMAL;
   }

   bool IsConstant() const {
@@ -266,7 +260,7 @@
     return IsDescriptorOrDictionary() && type() == CONSTANT;
   }

-  bool IsDontDelete() const { return details_.IsDontDelete(); }
+  bool IsConfigurable() const { return details_.IsConfigurable(); }
   bool IsDontEnum() const { return details_.IsDontEnum(); }
   bool IsFound() const { return lookup_type_ != NOT_FOUND; }
   bool IsDescriptorOrDictionary() const {
=======================================
--- /trunk/src/runtime.cc       Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/runtime.cc       Fri Aug 22 00:04:38 2014 UTC
@@ -5027,15 +5027,12 @@
     return isolate->heap()->undefined_value();
   }

-  LookupResult lookup(isolate);
-  js_object->LookupOwnRealNamedProperty(name, &lookup);
+  LookupIterator it(js_object, name, LookupIterator::CHECK_PROPERTY);

   // Take special care when attributes are different and there is already
-  // a property. For simplicity we normalize the property which enables us
-  // to not worry about changing the instance_descriptor and creating a new
-  // map.
-  if (lookup.IsFound() &&
-      (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
+  // a property.
+  if (it.IsFound() && it.HasProperty() &&
+      it.property_kind() == LookupIterator::ACCESSOR) {
     // Use IgnoreAttributes version since a readonly property may be
     // overridden and SetProperty does not allow this.
     Handle<Object> result;
=======================================
--- /trunk/src/version.cc       Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/version.cc       Fri Aug 22 00:04:38 2014 UTC
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     29
-#define BUILD_NUMBER      11
+#define BUILD_NUMBER      14
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/test/cctest/cctest.status    Thu Aug 21 00:04:56 2014 UTC
+++ /trunk/test/cctest/cctest.status    Fri Aug 22 00:04:38 2014 UTC
@@ -77,6 +77,9 @@
   'test-cpu-profiler/*': [PASS, FLAKY],
   'test-cpu-profiler/*': [SKIP],

+  # BUG(3525). Test crashes flakily.
+  'test-debug/RecursiveBreakpoints': [PASS, FLAKY],
+
##############################################################################
   # TurboFan compiler failures.

=======================================
--- /trunk/test/cctest/test-api.cc      Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/test/cctest/test-api.cc      Fri Aug 22 00:04:38 2014 UTC
@@ -21771,7 +21771,6 @@

   // Create a context and set an x property on it's global object.
   LocalContext context0(NULL, global_template);
-  context0->Global()->Set(v8_str("x"), v8_num(42));
   v8::Handle<v8::Object> global0 = context0->Global();

   // Create a context with a different security token so that the
=======================================
--- /trunk/test/mjsunit/es6/array-iterator.js   Fri Aug  8 15:46:17 2014 UTC
+++ /trunk/test/mjsunit/es6/array-iterator.js   Fri Aug 22 00:04:38 2014 UTC
@@ -175,10 +175,9 @@

   assertEquals(8, buffer.length);

-  for (var i = 0; i < buffer.length - 1; i++) {
+  for (var i = 0; i < buffer.length; i++) {
     assertSame(array[i], buffer[i]);
   }
-  assertTrue(isNaN(buffer[buffer.length - 1]));
 }
 TestForArrayValues();

@@ -210,10 +209,9 @@

   assertEquals(8, buffer.length);

-  for (var i = 0; i < buffer.length - 1; i++) {
+  for (var i = 0; i < buffer.length; i++) {
     assertSame(array[i], buffer[i][1]);
   }
-  assertTrue(isNaN(buffer[buffer.length - 1][1]));

   for (var i = 0; i < buffer.length; i++) {
     assertEquals(i, buffer[i][0]);
@@ -232,10 +230,9 @@

   assertEquals(8, buffer.length);

-  for (var i = 0; i < buffer.length - 1; i++) {
+  for (var i = 0; i < buffer.length; i++) {
     assertSame(array[i], buffer[i]);
   }
-  assertTrue(isNaN(buffer[buffer.length - 1]));
 }
 TestForArrayValues();

=======================================
--- /trunk/tools/run-tests.py   Wed Aug 20 00:06:26 2014 UTC
+++ /trunk/tools/run-tests.py   Fri Aug 22 00:04:38 2014 UTC
@@ -295,10 +295,15 @@
     return reduce(lambda x, y: x + y, args) <= 1

   if not excl(options.no_stress, options.stress_only, options.no_variants,
-              bool(options.variants), options.quickcheck):
+              bool(options.variants)):
     print("Use only one of --no-stress, --stress-only, --no-variants, "
-          "--variants, or --quickcheck.")
+          "or --variants.")
     return False
+  if options.quickcheck:
+    VARIANTS = ["default", "stress"]
+    options.flaky_tests = "skip"
+    options.slow_tests = "skip"
+    options.pass_fail_tests = "skip"
   if options.no_stress:
     VARIANTS = ["default", "nocrankshaft"]
   if options.no_variants:
@@ -310,11 +315,6 @@
     if not set(VARIANTS).issubset(VARIANT_FLAGS.keys()):
       print "All variants must be in %s" % str(VARIANT_FLAGS.keys())
       return False
-  if options.quickcheck:
-    VARIANTS = ["default", "stress"]
-    options.flaky_tests = "skip"
-    options.slow_tests = "skip"
-    options.pass_fail_tests = "skip"
   if options.predictable:
     VARIANTS = ["default"]
     options.extra_flags.append("--predictable")

--
--
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.

Reply via email to