aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2015-02-25 11:41:56 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2015-02-25 19:33:52 +0100
commit78f4837926105eb238068e12401493f4a7a17dbc (patch)
tree62c69fa81608cdb1c39d6fccb94e32b1111eef09
parent739fda16a93cadcefb59190669cfb7765d2fb8fa (diff)
downloadandroid-node-v8-78f4837926105eb238068e12401493f4a7a17dbc.tar.gz
android-node-v8-78f4837926105eb238068e12401493f4a7a17dbc.tar.bz2
android-node-v8-78f4837926105eb238068e12401493f4a7a17dbc.zip
deps: upgrade v8 to 4.1.0.21
PR-URL: https://github.com/iojs/io.js/pull/952 Reviewed-By: Fedor Indutny <fedor@indutny.com> Reviewed-By: Rod Vagg <rod@vagg.org>
-rw-r--r--deps/v8/include/v8.h17
-rw-r--r--deps/v8/src/api.cc35
-rw-r--r--deps/v8/src/flags.cc1
-rw-r--r--deps/v8/src/generator.js4
-rw-r--r--deps/v8/src/globals.h2
-rw-r--r--deps/v8/src/heap/mark-compact.cc5
-rw-r--r--deps/v8/src/heap/spaces.cc7
-rw-r--r--deps/v8/src/ic/ic.cc2
-rw-r--r--deps/v8/src/objects-inl.h1
-rw-r--r--deps/v8/src/objects.cc121
-rw-r--r--deps/v8/src/objects.h17
-rw-r--r--deps/v8/src/runtime/runtime-debug.cc3
-rw-r--r--deps/v8/src/runtime/runtime-regexp.cc2
-rw-r--r--deps/v8/src/serialize.cc65
-rw-r--r--deps/v8/src/serialize.h44
-rw-r--r--deps/v8/src/version.cc2
-rw-r--r--deps/v8/src/version.h5
-rw-r--r--deps/v8/test/cctest/test-api.cc2
-rw-r--r--deps/v8/test/cctest/test-serialize.cc50
-rw-r--r--deps/v8/test/mjsunit/es6/regress/regress-3902.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-430201.js41
-rw-r--r--deps/v8/tools/gen-postmortem-metadata.py14
22 files changed, 368 insertions, 87 deletions
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index d35f2fcb27..27aa5c12d1 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -3899,6 +3899,9 @@ class V8_EXPORT FunctionTemplate : public Template {
};
+enum class PropertyHandlerFlags { kNone = 0, kAllCanRead = 1 };
+
+
struct NamedPropertyHandlerConfiguration {
NamedPropertyHandlerConfiguration(
/** Note: getter is required **/
@@ -3907,13 +3910,15 @@ struct NamedPropertyHandlerConfiguration {
GenericNamedPropertyQueryCallback query = 0,
GenericNamedPropertyDeleterCallback deleter = 0,
GenericNamedPropertyEnumeratorCallback enumerator = 0,
- Handle<Value> data = Handle<Value>())
+ Handle<Value> data = Handle<Value>(),
+ PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
- data(data) {}
+ data(data),
+ flags(flags) {}
GenericNamedPropertyGetterCallback getter;
GenericNamedPropertySetterCallback setter;
@@ -3921,6 +3926,7 @@ struct NamedPropertyHandlerConfiguration {
GenericNamedPropertyDeleterCallback deleter;
GenericNamedPropertyEnumeratorCallback enumerator;
Handle<Value> data;
+ PropertyHandlerFlags flags;
};
@@ -3932,13 +3938,15 @@ struct IndexedPropertyHandlerConfiguration {
IndexedPropertyQueryCallback query = 0,
IndexedPropertyDeleterCallback deleter = 0,
IndexedPropertyEnumeratorCallback enumerator = 0,
- Handle<Value> data = Handle<Value>())
+ Handle<Value> data = Handle<Value>(),
+ PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
- data(data) {}
+ data(data),
+ flags(flags) {}
IndexedPropertyGetterCallback getter;
IndexedPropertySetterCallback setter;
@@ -3946,6 +3954,7 @@ struct IndexedPropertyHandlerConfiguration {
IndexedPropertyDeleterCallback deleter;
IndexedPropertyEnumeratorCallback enumerator;
Handle<Value> data;
+ PropertyHandlerFlags flags;
};
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 88d3c889b9..80afca28f3 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -1306,12 +1306,10 @@ void ObjectTemplate::SetAccessor(v8::Handle<Name> name,
template <typename Getter, typename Setter, typename Query, typename Deleter,
typename Enumerator>
-static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
- Getter getter, Setter setter,
- Query query, Deleter remover,
- Enumerator enumerator,
- Handle<Value> data,
- bool can_intercept_symbols) {
+static void ObjectTemplateSetNamedPropertyHandler(
+ ObjectTemplate* templ, Getter getter, Setter setter, Query query,
+ Deleter remover, Enumerator enumerator, Handle<Value> data,
+ bool can_intercept_symbols, PropertyHandlerFlags flags) {
i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
@@ -1319,10 +1317,8 @@ static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
i::FunctionTemplateInfo* constructor =
i::FunctionTemplateInfo::cast(Utils::OpenHandle(templ)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
- i::Handle<i::InterceptorInfo> obj =
- i::Handle<i::InterceptorInfo>::cast(struct_obj);
+ auto obj = i::Handle<i::InterceptorInfo>::cast(
+ isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
@@ -1331,6 +1327,8 @@ static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
obj->set_flags(0);
obj->set_can_intercept_symbols(can_intercept_symbols);
+ obj->set_all_can_read(static_cast<int>(flags) &
+ static_cast<int>(PropertyHandlerFlags::kAllCanRead));
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@@ -1345,15 +1343,16 @@ void ObjectTemplate::SetNamedPropertyHandler(
NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
NamedPropertyEnumeratorCallback enumerator, Handle<Value> data) {
ObjectTemplateSetNamedPropertyHandler(this, getter, setter, query, remover,
- enumerator, data, false);
+ enumerator, data, false,
+ PropertyHandlerFlags::kNone);
}
void ObjectTemplate::SetHandler(
const NamedPropertyHandlerConfiguration& config) {
- ObjectTemplateSetNamedPropertyHandler(this, config.getter, config.setter,
- config.query, config.deleter,
- config.enumerator, config.data, true);
+ ObjectTemplateSetNamedPropertyHandler(
+ this, config.getter, config.setter, config.query, config.deleter,
+ config.enumerator, config.data, true, config.flags);
}
@@ -1409,10 +1408,8 @@ void ObjectTemplate::SetHandler(
i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
Utils::OpenHandle(this)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
- i::Handle<i::InterceptorInfo> obj =
- i::Handle<i::InterceptorInfo>::cast(struct_obj);
+ auto obj = i::Handle<i::InterceptorInfo>::cast(
+ isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
@@ -1422,6 +1419,8 @@ void ObjectTemplate::SetHandler(
SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
}
obj->set_flags(0);
+ obj->set_all_can_read(static_cast<int>(config.flags) &
+ static_cast<int>(PropertyHandlerFlags::kAllCanRead));
v8::Local<v8::Value> data = config.data;
if (data.IsEmpty()) {
diff --git a/deps/v8/src/flags.cc b/deps/v8/src/flags.cc
index 2aa4e6bd48..5e33bdaeec 100644
--- a/deps/v8/src/flags.cc
+++ b/deps/v8/src/flags.cc
@@ -556,6 +556,7 @@ uint32_t FlagList::Hash() {
for (size_t i = 0; i < num_flags; ++i) {
Flag* current = &flags[i];
if (!current->IsDefault()) {
+ modified_args_as_string << i;
modified_args_as_string << *current;
}
}
diff --git a/deps/v8/src/generator.js b/deps/v8/src/generator.js
index 8e9ed8f256..9ab7dcb9aa 100644
--- a/deps/v8/src/generator.js
+++ b/deps/v8/src/generator.js
@@ -97,7 +97,7 @@ function SetUpGenerators() {
%AddNamedProperty(GeneratorObjectPrototype, symbolIterator,
GeneratorObjectIterator, DONT_ENUM | DONT_DELETE | READ_ONLY);
%AddNamedProperty(GeneratorObjectPrototype, "constructor",
- GeneratorFunctionPrototype, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
%AddNamedProperty(GeneratorObjectPrototype,
symbolToStringTag, "Generator", DONT_ENUM | READ_ONLY);
%InternalSetPrototype(GeneratorFunctionPrototype, $Function.prototype);
@@ -105,7 +105,7 @@ function SetUpGenerators() {
symbolToStringTag, "GeneratorFunction", DONT_ENUM | READ_ONLY);
%SetCode(GeneratorFunctionPrototype, GeneratorFunctionPrototypeConstructor);
%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
- GeneratorFunction, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ GeneratorFunction, DONT_ENUM | READ_ONLY);
%InternalSetPrototype(GeneratorFunction, $Function);
%SetCode(GeneratorFunction, GeneratorFunctionConstructor);
}
diff --git a/deps/v8/src/globals.h b/deps/v8/src/globals.h
index 48bb030b82..52ec2aaaa4 100644
--- a/deps/v8/src/globals.h
+++ b/deps/v8/src/globals.h
@@ -84,7 +84,7 @@ namespace internal {
// Determine whether double field unboxing feature is enabled.
#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64)
-#define V8_DOUBLE_FIELDS_UNBOXING 1
+#define V8_DOUBLE_FIELDS_UNBOXING 0
#else
#define V8_DOUBLE_FIELDS_UNBOXING 0
#endif
diff --git a/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc
index fa127db612..c9a310a3f7 100644
--- a/deps/v8/src/heap/mark-compact.cc
+++ b/deps/v8/src/heap/mark-compact.cc
@@ -3052,6 +3052,11 @@ void MarkCompactCollector::EvacuatePages() {
// have an emergency page and the space still has room for that.
if (space->HasEmergencyMemory() && space->CanExpand()) {
EvacuateLiveObjectsFromPage(p);
+ // Unlink the page from the list of pages here. We must not iterate
+ // over that page later (e.g. when scan on scavenge pages are
+ // processed). The page itself will be freed later and is still
+ // reachable from the evacuation candidates list.
+ p->Unlink();
} else {
// Without room for expansion evacuation is not guaranteed to succeed.
// Pessimistically abandon unevacuated pages.
diff --git a/deps/v8/src/heap/spaces.cc b/deps/v8/src/heap/spaces.cc
index 3802e470bd..060052e706 100644
--- a/deps/v8/src/heap/spaces.cc
+++ b/deps/v8/src/heap/spaces.cc
@@ -1142,7 +1142,12 @@ void PagedSpace::ReleasePage(Page* page) {
allocation_info_.set_limit(NULL);
}
- page->Unlink();
+ // If page is still in a list, unlink it from that list.
+ if (page->next_chunk() != NULL) {
+ DCHECK(page->prev_chunk() != NULL);
+ page->Unlink();
+ }
+
if (page->IsFlagSet(MemoryChunk::CONTAINS_ONLY_DATA)) {
heap()->isolate()->memory_allocator()->Free(page);
} else {
diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc
index 48cef68f5a..0707536b84 100644
--- a/deps/v8/src/ic/ic.cc
+++ b/deps/v8/src/ic/ic.cc
@@ -2924,7 +2924,7 @@ RUNTIME_FUNCTION(LoadElementWithInterceptor) {
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- JSObject::GetElementWithInterceptor(receiver, receiver, index));
+ JSObject::GetElementWithInterceptor(receiver, receiver, index, true));
return *result;
}
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index 485560f293..fdfadb1883 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -5517,6 +5517,7 @@ ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
kCanInterceptSymbolsBit)
+BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 414306f2b4..6b64c3fb21 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -572,12 +572,19 @@ MaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
static bool FindAllCanReadHolder(LookupIterator* it) {
- for (; it->IsFound(); it->Next()) {
+ // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
+ // which have already been checked.
+ DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
+ it->state() == LookupIterator::INTERCEPTOR);
+ for (it->Next(); it->IsFound(); it->Next()) {
if (it->state() == LookupIterator::ACCESSOR) {
- Handle<Object> accessors = it->GetAccessors();
+ auto accessors = it->GetAccessors();
if (accessors->IsAccessorInfo()) {
if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
}
+ } else if (it->state() == LookupIterator::INTERCEPTOR) {
+ auto holder = it->GetHolder<JSObject>();
+ if (holder->GetNamedInterceptor()->all_can_read()) return true;
}
}
return false;
@@ -587,10 +594,18 @@ static bool FindAllCanReadHolder(LookupIterator* it) {
MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
LookupIterator* it) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
- if (FindAllCanReadHolder(it)) {
- return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
- it->GetHolder<JSObject>(),
- it->GetAccessors());
+ while (FindAllCanReadHolder(it)) {
+ if (it->state() == LookupIterator::ACCESSOR) {
+ return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
+ it->GetHolder<JSObject>(),
+ it->GetAccessors());
+ }
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
+ auto receiver = Handle<JSObject>::cast(it->GetReceiver());
+ auto result = GetPropertyWithInterceptor(it->GetHolder<JSObject>(),
+ receiver, it->name());
+ if (it->isolate()->has_scheduled_exception()) break;
+ if (!result.is_null()) return result;
}
it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
@@ -601,8 +616,16 @@ MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
LookupIterator* it) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
- if (FindAllCanReadHolder(it))
- return maybe(it->property_details().attributes());
+ while (FindAllCanReadHolder(it)) {
+ if (it->state() == LookupIterator::ACCESSOR) {
+ return maybe(it->property_details().attributes());
+ }
+ DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
+ auto result = GetPropertyAttributesWithInterceptor(
+ it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
+ if (it->isolate()->has_scheduled_exception()) break;
+ if (result.has_value && result.value != ABSENT) return result;
+ }
it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
Maybe<PropertyAttributes>());
@@ -736,6 +759,65 @@ Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
}
+static MaybeHandle<JSObject> FindIndexedAllCanReadHolder(
+ Isolate* isolate, Handle<JSObject> js_object,
+ PrototypeIterator::WhereToStart where_to_start) {
+ for (PrototypeIterator iter(isolate, js_object, where_to_start);
+ !iter.IsAtEnd(); iter.Advance()) {
+ auto curr = PrototypeIterator::GetCurrent(iter);
+ if (!curr->IsJSObject()) break;
+ auto obj = Handle<JSObject>::cast(curr);
+ if (!obj->HasIndexedInterceptor()) continue;
+ if (obj->GetIndexedInterceptor()->all_can_read()) return obj;
+ }
+ return MaybeHandle<JSObject>();
+}
+
+
+MaybeHandle<Object> JSObject::GetElementWithFailedAccessCheck(
+ Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
+ uint32_t index) {
+ Handle<JSObject> holder = object;
+ PrototypeIterator::WhereToStart where_to_start =
+ PrototypeIterator::START_AT_RECEIVER;
+ while (true) {
+ auto all_can_read_holder =
+ FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
+ if (!all_can_read_holder.ToHandle(&holder)) break;
+ auto result =
+ JSObject::GetElementWithInterceptor(holder, receiver, index, false);
+ if (isolate->has_scheduled_exception()) break;
+ if (!result.is_null()) return result;
+ where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
+ }
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ return isolate->factory()->undefined_value();
+}
+
+
+Maybe<PropertyAttributes> JSObject::GetElementAttributesWithFailedAccessCheck(
+ Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
+ uint32_t index) {
+ Handle<JSObject> holder = object;
+ PrototypeIterator::WhereToStart where_to_start =
+ PrototypeIterator::START_AT_RECEIVER;
+ while (true) {
+ auto all_can_read_holder =
+ FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
+ if (!all_can_read_holder.ToHandle(&holder)) break;
+ auto result =
+ JSObject::GetElementAttributeFromInterceptor(object, receiver, index);
+ if (isolate->has_scheduled_exception()) break;
+ if (result.has_value && result.value != ABSENT) return result;
+ where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
+ }
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
+ return maybe(ABSENT);
+}
+
+
MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
Handle<Object> object,
Handle<Object> receiver,
@@ -768,14 +850,14 @@ MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
// Check access rights if needed.
if (js_object->IsAccessCheckNeeded()) {
if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return isolate->factory()->undefined_value();
+ return JSObject::GetElementWithFailedAccessCheck(isolate, js_object,
+ receiver, index);
}
}
if (js_object->HasIndexedInterceptor()) {
- return JSObject::GetElementWithInterceptor(js_object, receiver, index);
+ return JSObject::GetElementWithInterceptor(js_object, receiver, index,
+ true);
}
if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
@@ -4184,9 +4266,8 @@ Maybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver(
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
- RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
- return maybe(ABSENT);
+ return GetElementAttributesWithFailedAccessCheck(isolate, object,
+ receiver, index);
}
}
@@ -13383,10 +13464,10 @@ MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
}
-MaybeHandle<Object> JSObject::GetElementWithInterceptor(
- Handle<JSObject> object,
- Handle<Object> receiver,
- uint32_t index) {
+MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
+ Handle<Object> receiver,
+ uint32_t index,
+ bool check_prototype) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing
@@ -13411,6 +13492,8 @@ MaybeHandle<Object> JSObject::GetElementWithInterceptor(
}
}
+ if (!check_prototype) return MaybeHandle<Object>();
+
ElementsAccessor* handler = object->GetElementsAccessor();
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index f2f2e495b4..c32f9f6cca 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -1971,9 +1971,8 @@ class JSObject: public JSReceiver {
// Returns the index'th element.
// The undefined object if index is out of bounds.
MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
- Handle<JSObject> object,
- Handle<Object> receiver,
- uint32_t index);
+ Handle<JSObject> object, Handle<Object> receiver, uint32_t index,
+ bool check_prototype);
enum SetFastElementsCapacitySmiMode {
kAllowSmiElements,
@@ -2336,6 +2335,14 @@ class JSObject: public JSReceiver {
Handle<Object> value,
StrictMode strict_mode,
bool check_prototype = true);
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithFailedAccessCheck(
+ Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
+ uint32_t index);
+ MUST_USE_RESULT static Maybe<PropertyAttributes>
+ GetElementAttributesWithFailedAccessCheck(Isolate* isolate,
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ uint32_t index);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
@@ -7062,8 +7069,6 @@ class SharedFunctionInfo: public HeapObject {
static const int kUniqueIdOffset = kFeedbackVectorOffset + kPointerSize;
static const int kLastPointerFieldOffset = kUniqueIdOffset;
#else
- // Just to not break the postmortem support with conditional offsets
- static const int kUniqueIdOffset = kFeedbackVectorOffset;
static const int kLastPointerFieldOffset = kFeedbackVectorOffset;
#endif
@@ -10642,6 +10647,7 @@ class InterceptorInfo: public Struct {
DECL_ACCESSORS(enumerator, Object)
DECL_ACCESSORS(data, Object)
DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
+ DECL_BOOLEAN_ACCESSORS(all_can_read)
inline int flags() const;
inline void set_flags(int flags);
@@ -10662,6 +10668,7 @@ class InterceptorInfo: public Struct {
static const int kSize = kFlagsOffset + kPointerSize;
static const int kCanInterceptSymbolsBit = 0;
+ static const int kAllCanReadBit = 1;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc
index 12c5a0d84f..9b71a4f95e 100644
--- a/deps/v8/src/runtime/runtime-debug.cc
+++ b/deps/v8/src/runtime/runtime-debug.cc
@@ -246,7 +246,8 @@ RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
+ isolate, result,
+ JSObject::GetElementWithInterceptor(obj, obj, index, true));
return *result;
}
diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc
index be9adfff41..9296a4b8a9 100644
--- a/deps/v8/src/runtime/runtime-regexp.cc
+++ b/deps/v8/src/runtime/runtime-regexp.cc
@@ -278,7 +278,7 @@ void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
}
-void FindOneByteStringIndices(Vector<const uint8_t> subject, char pattern,
+void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern,
ZoneList<int>* indices, unsigned int limit,
Zone* zone) {
DCHECK(limit > 0);
diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc
index 01c55a1226..c5f8b6344e 100644
--- a/deps/v8/src/serialize.cc
+++ b/deps/v8/src/serialize.cc
@@ -2054,6 +2054,10 @@ void Serializer::Pad() {
for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) {
sink_->Put(kNop, "Padding");
}
+ // Pad up to pointer size for checksum.
+ while (!IsAligned(sink_->Position(), kPointerAlignment)) {
+ sink_->Put(kNop, "Padding");
+ }
}
@@ -2394,6 +2398,41 @@ Vector<const byte> SnapshotData::Payload() const {
}
+class Checksum {
+ public:
+ explicit Checksum(Vector<const byte> payload) {
+ // Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit.
+ uintptr_t a = 1;
+ uintptr_t b = 0;
+ const uintptr_t* cur = reinterpret_cast<const uintptr_t*>(payload.start());
+ DCHECK(IsAligned(payload.length(), kIntptrSize));
+ const uintptr_t* end = cur + payload.length() / kIntptrSize;
+ while (cur < end) {
+ // Unsigned overflow expected and intended.
+ a += *cur++;
+ b += a;
+ }
+#if V8_HOST_ARCH_64_BIT
+ a ^= a >> 32;
+ b ^= b >> 32;
+#endif // V8_HOST_ARCH_64_BIT
+ a_ = static_cast<uint32_t>(a);
+ b_ = static_cast<uint32_t>(b);
+ }
+
+ bool Check(uint32_t a, uint32_t b) const { return a == a_ && b == b_; }
+
+ uint32_t a() const { return a_; }
+ uint32_t b() const { return b_; }
+
+ private:
+ uint32_t a_;
+ uint32_t b_;
+
+ DISALLOW_COPY_AND_ASSIGN(Checksum);
+};
+
+
SerializedCodeData::SerializedCodeData(const List<byte>& payload,
const CodeSerializer& cs) {
DisallowHeapAllocation no_gc;
@@ -2412,12 +2451,20 @@ SerializedCodeData::SerializedCodeData(const List<byte>& payload,
AllocateData(size);
// Set header values.
- SetHeaderValue(kCheckSumOffset, CheckSum(cs.source()));
+ SetHeaderValue(kVersionHashOffset, Version::Hash());
+ SetHeaderValue(kSourceHashOffset, SourceHash(cs.source()));
+ SetHeaderValue(kCpuFeaturesOffset,
+ static_cast<uint32_t>(CpuFeatures::SupportedFeatures()));
+ SetHeaderValue(kFlagHashOffset, FlagList::Hash());
SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings());
SetHeaderValue(kReservationsOffset, reservations.length());
SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
SetHeaderValue(kPayloadLengthOffset, payload.length());
+ Checksum checksum(payload.ToConstVector());
+ SetHeaderValue(kChecksum1Offset, checksum.a());
+ SetHeaderValue(kChecksum2Offset, checksum.b());
+
// Copy reservation chunk sizes.
CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
reservation_size);
@@ -2432,14 +2479,14 @@ SerializedCodeData::SerializedCodeData(const List<byte>& payload,
}
-bool SerializedCodeData::IsSane(String* source) {
- return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
- Payload().length() >= SharedFunctionInfo::kSize;
-}
-
-
-int SerializedCodeData::CheckSum(String* string) {
- return Version::Hash() ^ string->length();
+bool SerializedCodeData::IsSane(String* source) const {
+ return GetHeaderValue(kVersionHashOffset) == Version::Hash() &&
+ GetHeaderValue(kSourceHashOffset) == SourceHash(source) &&
+ GetHeaderValue(kCpuFeaturesOffset) ==
+ static_cast<uint32_t>(CpuFeatures::SupportedFeatures()) &&
+ GetHeaderValue(kFlagHashOffset) == FlagList::Hash() &&
+ Checksum(Payload()).Check(GetHeaderValue(kChecksum1Offset),
+ GetHeaderValue(kChecksum2Offset));
}
diff --git a/deps/v8/src/serialize.h b/deps/v8/src/serialize.h
index bd0c423a6a..da750cb3c6 100644
--- a/deps/v8/src/serialize.h
+++ b/deps/v8/src/serialize.h
@@ -481,12 +481,14 @@ class SerializedData {
class IsLastChunkBits : public BitField<bool, 31, 1> {};
protected:
- void SetHeaderValue(int offset, int value) {
- reinterpret_cast<int*>(data_)[offset] = value;
+ void SetHeaderValue(int offset, uint32_t value) {
+ memcpy(reinterpret_cast<uint32_t*>(data_) + offset, &value, sizeof(value));
}
- int GetHeaderValue(int offset) const {
- return reinterpret_cast<const int*>(data_)[offset];
+ uint32_t GetHeaderValue(int offset) const {
+ uint32_t value;
+ memcpy(&value, reinterpret_cast<int*>(data_) + offset, sizeof(value));
+ return value;
}
void AllocateData(int size);
@@ -920,22 +922,32 @@ class SerializedCodeData : public SerializedData {
explicit SerializedCodeData(ScriptData* data)
: SerializedData(const_cast<byte*>(data->data()), data->length()) {}
- bool IsSane(String* source);
+ bool IsSane(String* source) const;
- int CheckSum(String* source);
+ static uint32_t SourceHash(String* source) { return source->length(); }
// The data header consists of int-sized entries:
// [0] version hash
- // [1] number of internalized strings
- // [2] number of code stub keys
- // [3] number of reservation size entries
- // [4] payload length
- static const int kCheckSumOffset = 0;
- static const int kNumInternalizedStringsOffset = 1;
- static const int kReservationsOffset = 2;
- static const int kNumCodeStubKeysOffset = 3;
- static const int kPayloadLengthOffset = 4;
- static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
+ // [1] source hash
+ // [2] cpu features
+ // [3] flag hash
+ // [4] number of internalized strings
+ // [5] number of code stub keys
+ // [6] number of reservation size entries
+ // [7] payload length
+ // [8] checksum 1
+ // [9] checksum 2
+ static const int kVersionHashOffset = 0;
+ static const int kSourceHashOffset = 1;
+ static const int kCpuFeaturesOffset = 2;
+ static const int kFlagHashOffset = 3;
+ static const int kNumInternalizedStringsOffset = 4;
+ static const int kReservationsOffset = 5;
+ static const int kNumCodeStubKeysOffset = 6;
+ static const int kPayloadLengthOffset = 7;
+ static const int kChecksum1Offset = 8;
+ static const int kChecksum2Offset = 9;
+ static const int kHeaderSize = (kChecksum2Offset + 1) * kIntSize;
};
} } // namespace v8::internal
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 3b1c220f57..edcf2be2db 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 4
#define MINOR_VERSION 1
#define BUILD_NUMBER 0
-#define PATCH_LEVEL 14
+#define PATCH_LEVEL 21
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/deps/v8/src/version.h b/deps/v8/src/version.h
index 008ed27654..dbcec1b27d 100644
--- a/deps/v8/src/version.h
+++ b/deps/v8/src/version.h
@@ -18,8 +18,9 @@ class Version {
static int GetBuild() { return build_; }
static int GetPatch() { return patch_; }
static bool IsCandidate() { return candidate_; }
- static int Hash() {
- return static_cast<int>(base::hash_combine(major_, minor_, build_, patch_));
+ static uint32_t Hash() {
+ return static_cast<uint32_t>(
+ base::hash_combine(major_, minor_, build_, patch_));
}
// Calculate the V8 version string.
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index d18059cd54..06cf5532e2 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -24540,7 +24540,7 @@ TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit2) {
void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
- const char* garbage = "garbage garbage garbage garbage.";
+ const char* garbage = "garbage garbage garbage garbage garbage garbage";
const uint8_t* data = reinterpret_cast<const uint8_t*>(garbage);
int length = 16;
v8::ScriptCompiler::CachedData* cached_data =
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index acd904f4b7..45da25024f 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -1156,6 +1156,56 @@ TEST(SerializeToplevelIsolates) {
}
+TEST(SerializeToplevelFlagChange) {
+ FLAG_serialize_toplevel = true;
+
+ const char* source = "function f() { return 'abc'; }; f() + 'def'";
+ v8::ScriptCompiler::CachedData* cache;
+
+ v8::Isolate* isolate1 = v8::Isolate::New();
+ {
+ v8::Isolate::Scope iscope(isolate1);
+ v8::HandleScope scope(isolate1);
+ v8::Local<v8::Context> context = v8::Context::New(isolate1);
+ v8::Context::Scope context_scope(context);
+
+ v8::Local<v8::String> source_str = v8_str(source);
+ v8::ScriptOrigin origin(v8_str("test"));
+ v8::ScriptCompiler::Source source(source_str, origin);
+ v8::Local<v8::UnboundScript> script = v8::ScriptCompiler::CompileUnbound(
+ isolate1, &source, v8::ScriptCompiler::kProduceCodeCache);
+ const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
+ CHECK(data);
+ // Persist cached data.
+ uint8_t* buffer = NewArray<uint8_t>(data->length);
+ MemCopy(buffer, data->data, data->length);
+ cache = new v8::ScriptCompiler::CachedData(
+ buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
+
+ v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
+ CHECK(result->ToString(isolate1)->Equals(v8_str("abcdef")));
+ }
+ isolate1->Dispose();
+
+ v8::Isolate* isolate2 = v8::Isolate::New();
+ FLAG_allow_natives_syntax = true; // Flag change should trigger cache reject.
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ v8::HandleScope scope(isolate2);
+ v8::Local<v8::Context> context = v8::Context::New(isolate2);
+ v8::Context::Scope context_scope(context);
+
+ v8::Local<v8::String> source_str = v8_str(source);
+ v8::ScriptOrigin origin(v8_str("test"));
+ v8::ScriptCompiler::Source source(source_str, origin, cache);
+ v8::ScriptCompiler::CompileUnbound(isolate2, &source,
+ v8::ScriptCompiler::kConsumeCodeCache);
+ CHECK(cache->rejected);
+ }
+ isolate2->Dispose();
+}
+
+
TEST(SerializeWithHarmonyScoping) {
FLAG_serialize_toplevel = true;
FLAG_harmony_scoping = true;
diff --git a/deps/v8/test/mjsunit/es6/regress/regress-3902.js b/deps/v8/test/mjsunit/es6/regress/regress-3902.js
new file mode 100644
index 0000000000..768a4a1d07
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/regress/regress-3902.js
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+function* g() {}
+assertTrue(Object.getOwnPropertyDescriptor(g.__proto__, "constructor").configurable);
+assertTrue(Object.getOwnPropertyDescriptor(g.prototype.__proto__, "constructor").configurable);
+
+function FakeGeneratorFunctionConstructor() {}
+Object.defineProperty(g.__proto__, "constructor", {value: FakeGeneratorFunctionConstructor});
+assertSame(g.__proto__.constructor, FakeGeneratorFunctionConstructor);
+
+function FakeGeneratorObjectConstructor() {}
+Object.defineProperty(g.prototype.__proto__, "constructor", {value: FakeGeneratorObjectConstructor});
+assertSame(g.prototype.__proto__.constructor, FakeGeneratorObjectConstructor);
diff --git a/deps/v8/test/mjsunit/regress/regress-430201.js b/deps/v8/test/mjsunit/regress/regress-430201.js
new file mode 100644
index 0000000000..b53383e22e
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-430201.js
@@ -0,0 +1,41 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+var array_1 = [];
+
+%SetFlags("--stress-compaction");
+for (var a = 0; a < 10000; a++) { array_1[a * 100] = 0; }
+
+gc();
+gc();
+
+var array_2 = [];
+for (var i = 0; i < 321361; i++) {
+ array_2[i] = String.fromCharCode(i)[0];
+}
diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py
index 62e103a735..04a1ea87f4 100644
--- a/deps/v8/tools/gen-postmortem-metadata.py
+++ b/deps/v8/tools/gen-postmortem-metadata.py
@@ -70,6 +70,8 @@ consts_misc = [
{ 'name': 'ExternalStringTag', 'value': 'kExternalStringTag' },
{ 'name': 'SlicedStringTag', 'value': 'kSlicedStringTag' },
+ { 'name': 'FailureTag', 'value': 'kFailureTag' },
+ { 'name': 'FailureTagMask', 'value': 'kFailureTagMask' },
{ 'name': 'HeapObjectTag', 'value': 'kHeapObjectTag' },
{ 'name': 'HeapObjectTagMask', 'value': 'kHeapObjectTagMask' },
{ 'name': 'SmiTag', 'value': 'kSmiTag' },
@@ -92,6 +94,8 @@ consts_misc = [
'value': 'DescriptorArray::kFirstIndex' },
{ 'name': 'prop_type_field',
'value': 'FIELD' },
+ { 'name': 'prop_type_first_phantom',
+ 'value': 'TRANSITION' },
{ 'name': 'prop_type_mask',
'value': 'PropertyDetails::TypeField::kMask' },
{ 'name': 'prop_index_mask',
@@ -116,9 +120,9 @@ consts_misc = [
'value': 'DICTIONARY_ELEMENTS' },
{ 'name': 'bit_field2_elements_kind_mask',
- 'value': 'Map::ElementsKindBits::kMask' },
+ 'value': 'Map::kElementsKindMask' },
{ 'name': 'bit_field2_elements_kind_shift',
- 'value': 'Map::ElementsKindBits::kShift' },
+ 'value': 'Map::kElementsKindShift' },
{ 'name': 'bit_field3_dictionary_map_shift',
'value': 'Map::DictionaryMap::kShift' },
@@ -192,9 +196,9 @@ header = '''
* This file is generated by %s. Do not edit directly.
*/
-#include "src/v8.h"
-#include "src/frames.h"
-#include "src/frames-inl.h" /* for architecture-specific frame constants */
+#include "v8.h"
+#include "frames.h"
+#include "frames-inl.h" /* for architecture-specific frame constants */
using namespace v8::internal;