Update V8 to version 4.1.0.21
This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.
Original commit message:
Version 4.1.0.21 (cherry-pick)
Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412
Unlink pages from the space page list after evacuation.
BUG=430201
LOG=N
R=jkummerow@chromium.org
Review URL: https://codereview.chromium.org/953813002
Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}
---
FPIIM-449
Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/src/factory.cc b/src/factory.cc
index 45a79c1..ba62341 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -139,12 +139,12 @@
Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
- return OrderedHashSet::Allocate(isolate(), 4);
+ return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity);
}
Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
- return OrderedHashMap::Allocate(isolate(), 4);
+ return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity);
}
@@ -693,21 +693,31 @@
}
-Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function,
+Handle<Context> Factory::NewScriptContext(Handle<JSFunction> function,
Handle<ScopeInfo> scope_info) {
Handle<FixedArray> array =
NewFixedArray(scope_info->ContextLength(), TENURED);
- array->set_map_no_write_barrier(*global_context_map());
+ array->set_map_no_write_barrier(*script_context_map());
Handle<Context> context = Handle<Context>::cast(array);
context->set_closure(*function);
context->set_previous(function->context());
context->set_extension(*scope_info);
context->set_global_object(function->context()->global_object());
- DCHECK(context->IsGlobalContext());
+ DCHECK(context->IsScriptContext());
return context;
}
+Handle<ScriptContextTable> Factory::NewScriptContextTable() {
+ Handle<FixedArray> array = NewFixedArray(1);
+ array->set_map_no_write_barrier(*script_context_table_map());
+ Handle<ScriptContextTable> context_table =
+ Handle<ScriptContextTable>::cast(array);
+ context_table->set_used(0);
+ return context_table;
+}
+
+
Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
Handle<FixedArray> array =
NewFixedArray(scope_info->ContextLength(), TENURED);
@@ -792,6 +802,7 @@
Handle<CodeCache>::cast(NewStruct(CODE_CACHE_TYPE));
code_cache->set_default_cache(*empty_fixed_array(), SKIP_WRITE_BARRIER);
code_cache->set_normal_type_cache(*undefined_value(), SKIP_WRITE_BARRIER);
+ code_cache->set_weak_cell_cache(*undefined_value(), SKIP_WRITE_BARRIER);
return code_cache;
}
@@ -837,7 +848,6 @@
heap->set_last_script_id(Smi::FromInt(id));
// Create and initialize script object.
- Handle<Foreign> wrapper = NewForeign(0, TENURED);
Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
script->set_source(*source);
script->set_name(heap->undefined_value());
@@ -846,7 +856,7 @@
script->set_column_offset(Smi::FromInt(0));
script->set_context_data(heap->undefined_value());
script->set_type(Smi::FromInt(Script::TYPE_NORMAL));
- script->set_wrapper(*wrapper);
+ script->set_wrapper(heap->undefined_value());
script->set_line_ends(heap->undefined_value());
script->set_eval_from_shared(heap->undefined_value());
script->set_eval_from_instructions_offset(Smi::FromInt(0));
@@ -931,6 +941,13 @@
}
+Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) {
+ AllowDeferredHandleDereference convert_to_cell;
+ CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateWeakCell(*value),
+ WeakCell);
+}
+
+
Handle<AllocationSite> Factory::NewAllocationSite() {
Handle<Map> map = allocation_site_map();
Handle<AllocationSite> site = New<AllocationSite>(map, OLD_POINTER_SPACE);
@@ -1018,7 +1035,7 @@
// patterns is faster than using fpclassify() et al.
if (IsMinusZero(value)) return NewHeapNumber(-0.0, IMMUTABLE, pretenure);
- int int_value = FastD2I(value);
+ int int_value = FastD2IChecked(value);
if (value == int_value && Smi::IsValid(int_value)) {
return handle(Smi::FromInt(int_value), isolate());
}
@@ -1292,20 +1309,25 @@
}
-Handle<JSFunction> Factory::NewFunction(Handle<String> name,
- Handle<Code> code,
+Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
- InstanceType type,
- int instance_size,
- bool read_only_prototype) {
+ InstanceType type, int instance_size,
+ bool read_only_prototype,
+ bool install_constructor) {
// Allocate the function
Handle<JSFunction> function = NewFunction(
name, code, prototype, read_only_prototype);
- Handle<Map> initial_map = NewMap(
- type, instance_size, GetInitialFastElementsKind());
- if (prototype->IsTheHole() && !function->shared()->is_generator()) {
- prototype = NewFunctionPrototype(function);
+ ElementsKind elements_kind =
+ type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;
+ Handle<Map> initial_map = NewMap(type, instance_size, elements_kind);
+ if (!function->shared()->is_generator()) {
+ if (prototype->IsTheHole()) {
+ prototype = NewFunctionPrototype(function);
+ } else if (install_constructor) {
+ JSObject::AddProperty(Handle<JSObject>::cast(prototype),
+ constructor_string(), function, DONT_ENUM);
+ }
}
JSFunction::SetInitialMap(function, initial_map,
@@ -1351,6 +1373,14 @@
}
+static bool ShouldOptimizeNewClosure(Isolate* isolate,
+ Handle<SharedFunctionInfo> info) {
+ return isolate->use_crankshaft() && !info->is_toplevel() &&
+ info->is_compiled() && info->allows_lazy_compilation() &&
+ !info->optimization_disabled() && !isolate->DebuggerHasBreakPoints();
+}
+
+
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> info,
Handle<Context> context,
@@ -1388,13 +1418,7 @@
return result;
}
- if (isolate()->use_crankshaft() &&
- FLAG_always_opt &&
- result->is_compiled() &&
- !info->is_toplevel() &&
- info->allows_lazy_compilation() &&
- !info->optimization_disabled() &&
- !isolate()->DebuggerHasBreakPoints()) {
+ if (FLAG_always_opt && ShouldOptimizeNewClosure(isolate(), info)) {
result->MarkForOptimization();
}
return result;
@@ -1568,7 +1592,7 @@
for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
PropertyDetails details = descs->GetDetails(i);
DCHECK(details.type() == CALLBACKS); // Only accessors are expected.
- PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1);
+ PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
Handle<Name> name(descs->GetKey(i));
Handle<Object> value(descs->GetCallbacksObject(i), isolate());
Handle<PropertyCell> cell = NewPropertyCell(value);
@@ -1658,6 +1682,7 @@
return;
}
+ HandleScope inner_scope(isolate());
Handle<FixedArrayBase> elms;
ElementsKind elements_kind = array->GetElementsKind();
if (IsFastDoubleElementsKind(elements_kind)) {
@@ -1715,8 +1740,51 @@
}
-static JSFunction* GetTypedArrayFun(ExternalArrayType type,
- Isolate* isolate) {
+Handle<JSMapIterator> Factory::NewJSMapIterator() {
+ Handle<Map> map(isolate()->native_context()->map_iterator_map());
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateJSObjectFromMap(*map),
+ JSMapIterator);
+}
+
+
+Handle<JSSetIterator> Factory::NewJSSetIterator() {
+ Handle<Map> map(isolate()->native_context()->set_iterator_map());
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateJSObjectFromMap(*map),
+ JSSetIterator);
+}
+
+
+namespace {
+
+ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
+ switch (type) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case kExternal##Type##Array: \
+ return EXTERNAL_##TYPE##_ELEMENTS;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ }
+ UNREACHABLE();
+ return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND;
+#undef TYPED_ARRAY_CASE
+}
+
+
+size_t GetExternalArrayElementSize(ExternalArrayType type) {
+ switch (type) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case kExternal##Type##Array: \
+ return size;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ }
+ UNREACHABLE();
+ return 0;
+#undef TYPED_ARRAY_CASE
+}
+
+
+JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
Context* native_context = isolate->context()->native_context();
switch (type) {
#define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \
@@ -1733,6 +1801,31 @@
}
+void SetupArrayBufferView(i::Isolate* isolate,
+ i::Handle<i::JSArrayBufferView> obj,
+ i::Handle<i::JSArrayBuffer> buffer,
+ size_t byte_offset, size_t byte_length) {
+ DCHECK(byte_offset + byte_length <=
+ static_cast<size_t>(buffer->byte_length()->Number()));
+
+ obj->set_buffer(*buffer);
+
+ obj->set_weak_next(buffer->weak_first_view());
+ buffer->set_weak_first_view(*obj);
+
+ i::Handle<i::Object> byte_offset_object =
+ isolate->factory()->NewNumberFromSize(byte_offset);
+ obj->set_byte_offset(*byte_offset_object);
+
+ i::Handle<i::Object> byte_length_object =
+ isolate->factory()->NewNumberFromSize(byte_length);
+ obj->set_byte_length(*byte_length_object);
+}
+
+
+} // namespace
+
+
Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate()));
@@ -1743,13 +1836,50 @@
}
+Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
+ Handle<JSArrayBuffer> buffer,
+ size_t byte_offset,
+ size_t length) {
+ Handle<JSTypedArray> obj = NewJSTypedArray(type);
+
+ size_t element_size = GetExternalArrayElementSize(type);
+ ElementsKind elements_kind = GetExternalArrayElementsKind(type);
+
+ CHECK(byte_offset % element_size == 0);
+
+ CHECK(length <= (std::numeric_limits<size_t>::max() / element_size));
+ CHECK(length <= static_cast<size_t>(Smi::kMaxValue));
+ size_t byte_length = length * element_size;
+ SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
+
+ Handle<Object> length_object = NewNumberFromSize(length);
+ obj->set_length(*length_object);
+
+ Handle<ExternalArray> elements = NewExternalArray(
+ static_cast<int>(length), type,
+ static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
+ Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind);
+ JSObject::SetMapAndElements(obj, map, elements);
+ return obj;
+}
+
+
+Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
+ size_t byte_offset,
+ size_t byte_length) {
+ Handle<JSDataView> obj = NewJSDataView();
+ SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
+ return obj;
+}
+
+
Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
Handle<Object> prototype) {
// Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
- map->set_prototype(*prototype);
+ map->SetPrototype(prototype);
// Allocate the proxy object.
Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
@@ -1768,7 +1898,7 @@
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
- map->set_prototype(*prototype);
+ map->SetPrototype(prototype);
// Allocate the proxy object.
Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
@@ -1793,7 +1923,7 @@
int size_difference = proxy->map()->instance_size() - map->instance_size();
DCHECK(size_difference >= 0);
- map->set_prototype(proxy->map()->prototype());
+ map->SetPrototype(handle(proxy->map()->prototype(), proxy->GetIsolate()));
// Allocate the backing storage for the properties.
int prop_size = map->InitialPropertiesLength();
@@ -1886,20 +2016,9 @@
}
-Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(int slot_count) {
- // Ensure we can skip the write barrier
- DCHECK_EQ(isolate()->heap()->uninitialized_symbol(),
- *TypeFeedbackVector::UninitializedSentinel(isolate()));
-
- if (slot_count == 0) {
- return Handle<TypeFeedbackVector>::cast(empty_fixed_array());
- }
-
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateFixedArrayWithFiller(
- slot_count, TENURED,
- *TypeFeedbackVector::UninitializedSentinel(isolate())),
- TypeFeedbackVector);
+Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
+ const FeedbackVectorSpec& spec) {
+ return TypeFeedbackVector::Allocate(isolate(), spec);
}
@@ -1974,8 +2093,13 @@
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
- Handle<TypeFeedbackVector> feedback_vector = NewTypeFeedbackVector(0);
+ FeedbackVectorSpec empty_spec;
+ Handle<TypeFeedbackVector> feedback_vector =
+ NewTypeFeedbackVector(empty_spec);
share->set_feedback_vector(*feedback_vector, SKIP_WRITE_BARRIER);
+#if TRACE_MAPS
+ share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
+#endif
share->set_profiler_ticks(0);
share->set_ast_node_count(0);
share->set_counters(0);
@@ -2033,7 +2157,7 @@
// cache in the snapshot to keep boot-time memory usage down.
// If we expand the number string cache already while creating
// the snapshot then that didn't work out.
- DCHECK(!isolate()->serializer_enabled() || FLAG_extra_code != NULL);
+ DCHECK(!isolate()->serializer_enabled());
Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
isolate()->heap()->set_number_string_cache(*new_cache);
return;
@@ -2164,8 +2288,8 @@
break;
}
- result = NewFunction(empty_string(), code, prototype, type,
- instance_size, obj->read_only_prototype());
+ result = NewFunction(empty_string(), code, prototype, type, instance_size,
+ obj->read_only_prototype(), true);
}
result->shared()->set_length(obj->length());
@@ -2185,19 +2309,13 @@
return result;
}
- if (prototype->IsTheHole()) {
#ifdef DEBUG
- LookupIterator it(handle(JSObject::cast(result->prototype())),
- constructor_string(),
- LookupIterator::OWN_SKIP_INTERCEPTOR);
- MaybeHandle<Object> maybe_prop = Object::GetProperty(&it);
- DCHECK(it.IsFound());
- DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result));
+ LookupIterator it(handle(JSObject::cast(result->prototype())),
+ constructor_string(), LookupIterator::OWN_SKIP_INTERCEPTOR);
+ MaybeHandle<Object> maybe_prop = Object::GetProperty(&it);
+ DCHECK(it.IsFound());
+ DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result));
#endif
- } else {
- JSObject::AddProperty(handle(JSObject::cast(result->prototype())),
- constructor_string(), result, DONT_ENUM);
- }
// Down from here is only valid for API functions that can be used as a
// constructor (don't set the "remove prototype" flag).
@@ -2306,35 +2424,42 @@
}
-Handle<MapCache> Factory::AddToMapCache(Handle<Context> context,
- Handle<FixedArray> keys,
- Handle<Map> map) {
- Handle<MapCache> map_cache = handle(MapCache::cast(context->map_cache()));
- Handle<MapCache> result = MapCache::Put(map_cache, keys, map);
- context->set_map_cache(*result);
- return result;
-}
-
-
Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
- Handle<FixedArray> keys) {
+ int number_of_properties,
+ bool* is_result_from_cache) {
+ const int kMapCacheSize = 128;
+
+ if (number_of_properties > kMapCacheSize) {
+ *is_result_from_cache = false;
+ return Map::Create(isolate(), number_of_properties);
+ }
+ *is_result_from_cache = true;
+ if (number_of_properties == 0) {
+ // Reuse the initial map of the Object function if the literal has no
+ // predeclared properties.
+ return handle(context->object_function()->initial_map(), isolate());
+ }
+ int cache_index = number_of_properties - 1;
if (context->map_cache()->IsUndefined()) {
// Allocate the new map cache for the native context.
- Handle<MapCache> new_cache = MapCache::New(isolate(), 24);
+ Handle<FixedArray> new_cache = NewFixedArray(kMapCacheSize, TENURED);
context->set_map_cache(*new_cache);
}
// Check to see whether there is a matching element in the cache.
- Handle<MapCache> cache =
- Handle<MapCache>(MapCache::cast(context->map_cache()));
- Handle<Object> result = Handle<Object>(cache->Lookup(*keys), isolate());
- if (result->IsMap()) return Handle<Map>::cast(result);
- int length = keys->length();
- // Create a new map and add it to the cache. Reuse the initial map of the
- // Object function if the literal has no predeclared properties.
- Handle<Map> map = length == 0
- ? handle(context->object_function()->initial_map())
- : Map::Create(isolate(), length);
- AddToMapCache(context, keys, map);
+ Handle<FixedArray> cache(FixedArray::cast(context->map_cache()));
+ {
+ Object* result = cache->get(cache_index);
+ if (result->IsWeakCell()) {
+ WeakCell* cell = WeakCell::cast(result);
+ if (!cell->cleared()) {
+ return handle(Map::cast(cell->value()), isolate());
+ }
+ }
+ }
+ // Create a new map and add it to the cache.
+ Handle<Map> map = Map::Create(isolate(), number_of_properties);
+ Handle<WeakCell> cell = NewWeakCell(map);
+ cache->set(cache_index, *cell);
return map;
}
@@ -2353,6 +2478,7 @@
regexp->set_data(*store);
}
+
void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
JSRegExp::Type type,
Handle<String> source,
@@ -2374,7 +2500,6 @@
}
-
MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance(
Handle<FunctionTemplateInfo> desc, Handle<JSObject> instance) {
// Configure the instance by adding the properties specified by the