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.