[heap] remove heap init from shipping binary.
This reduces the arm32 binary by around 20kB. R=jkummerow@chromium.org, mstarzinger@chromium.org Bug: v8:6055 Change-Id: If9098e49793b29dceb8292aff6f668ca28a07728 Reviewed-on: https://chromium-review.googlesource.com/652427 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#47863}
This commit is contained in:
parent
eeadb48c28
commit
d4c6c7561c
15
BUILD.gn
15
BUILD.gn
@ -854,7 +854,7 @@ source_set("v8_maybe_snapshot") {
|
||||
} else {
|
||||
# Ignore v8_use_external_startup_data setting if no snapshot is used.
|
||||
public_deps = [
|
||||
":v8_builtins_setup",
|
||||
":v8_init",
|
||||
":v8_nosnapshot",
|
||||
]
|
||||
}
|
||||
@ -954,7 +954,7 @@ if (v8_use_external_startup_data) {
|
||||
}
|
||||
}
|
||||
|
||||
v8_source_set("v8_builtins_generators") {
|
||||
v8_source_set("v8_initializers") {
|
||||
visibility = [
|
||||
":*",
|
||||
"test/cctest:*",
|
||||
@ -1012,6 +1012,7 @@ v8_source_set("v8_builtins_generators") {
|
||||
"src/builtins/builtins-utils-gen.h",
|
||||
"src/builtins/builtins-wasm-gen.cc",
|
||||
"src/builtins/setup-builtins-internal.cc",
|
||||
"src/heap/setup-heap-internal.cc",
|
||||
"src/ic/accessor-assembler.cc",
|
||||
"src/ic/accessor-assembler.h",
|
||||
"src/ic/binary-op-assembler.cc",
|
||||
@ -1089,11 +1090,11 @@ v8_source_set("v8_builtins_generators") {
|
||||
configs = [ ":internal_config" ]
|
||||
}
|
||||
|
||||
v8_source_set("v8_builtins_setup") {
|
||||
v8_source_set("v8_init") {
|
||||
visibility = [ ":*" ] # Only targets in this file can depend on this.
|
||||
|
||||
deps = [
|
||||
":v8_builtins_generators",
|
||||
":v8_initializers",
|
||||
]
|
||||
|
||||
sources = [
|
||||
@ -2641,7 +2642,7 @@ if (current_toolchain == v8_snapshot_toolchain) {
|
||||
|
||||
deps = [
|
||||
":v8_base",
|
||||
":v8_builtins_setup",
|
||||
":v8_init",
|
||||
":v8_libbase",
|
||||
":v8_libplatform",
|
||||
":v8_nosnapshot",
|
||||
@ -2754,7 +2755,7 @@ if (is_component_build) {
|
||||
]
|
||||
|
||||
if (v8_use_snapshot) {
|
||||
public_deps += [ ":v8_builtins_generators" ]
|
||||
public_deps += [ ":v8_initializers" ]
|
||||
}
|
||||
|
||||
configs = [ ":internal_config" ]
|
||||
@ -2780,7 +2781,7 @@ if (is_component_build) {
|
||||
]
|
||||
|
||||
if (v8_use_snapshot) {
|
||||
public_deps += [ ":v8_builtins_generators" ]
|
||||
public_deps += [ ":v8_initializers" ]
|
||||
}
|
||||
|
||||
public_configs = [ ":external_config" ]
|
||||
|
602
src/heap/heap.cc
602
src/heap/heap.cc
@ -2461,325 +2461,6 @@ AllocationResult Heap::AllocateFillerObject(int size, bool double_align,
|
||||
}
|
||||
|
||||
|
||||
const Heap::StringTypeTable Heap::string_type_table[] = {
|
||||
#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
|
||||
{ type, size, k##camel_name##MapRootIndex } \
|
||||
,
|
||||
STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
|
||||
#undef STRING_TYPE_ELEMENT
|
||||
};
|
||||
|
||||
|
||||
const Heap::ConstantStringTable Heap::constant_string_table[] = {
|
||||
{"", kempty_stringRootIndex},
|
||||
#define CONSTANT_STRING_ELEMENT(name, contents) \
|
||||
{ contents, k##name##RootIndex } \
|
||||
,
|
||||
INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT)
|
||||
#undef CONSTANT_STRING_ELEMENT
|
||||
};
|
||||
|
||||
|
||||
const Heap::StructTable Heap::struct_table[] = {
|
||||
#define STRUCT_TABLE_ELEMENT(NAME, Name, name) \
|
||||
{ NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \
|
||||
,
|
||||
STRUCT_LIST(STRUCT_TABLE_ELEMENT)
|
||||
#undef STRUCT_TABLE_ELEMENT
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
void FinalizePartialMap(Heap* heap, Map* map) {
|
||||
map->set_code_cache(heap->empty_fixed_array());
|
||||
map->set_dependent_code(DependentCode::cast(heap->empty_fixed_array()));
|
||||
map->set_raw_transitions(Smi::kZero);
|
||||
map->set_instance_descriptors(heap->empty_descriptor_array());
|
||||
if (FLAG_unbox_double_fields) {
|
||||
map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
|
||||
}
|
||||
map->set_prototype(heap->null_value());
|
||||
map->set_constructor_or_backpointer(heap->null_value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Heap::CreateInitialMaps() {
|
||||
HeapObject* obj = nullptr;
|
||||
{
|
||||
AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
// Map::cast cannot be used due to uninitialized map field.
|
||||
Map* new_meta_map = reinterpret_cast<Map*>(obj);
|
||||
set_meta_map(new_meta_map);
|
||||
new_meta_map->set_map_after_allocation(new_meta_map);
|
||||
|
||||
{ // Partial map allocation
|
||||
#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \
|
||||
{ \
|
||||
Map* map; \
|
||||
if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \
|
||||
set_##field_name##_map(map); \
|
||||
}
|
||||
|
||||
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
|
||||
fixed_array_map()->set_elements_kind(HOLEY_ELEMENTS);
|
||||
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel,
|
||||
fixed_cow_array)
|
||||
fixed_cow_array_map()->set_elements_kind(HOLEY_ELEMENTS);
|
||||
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
|
||||
|
||||
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
|
||||
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
|
||||
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
|
||||
|
||||
#undef ALLOCATE_PARTIAL_MAP
|
||||
}
|
||||
|
||||
// Allocate the empty array.
|
||||
{
|
||||
AllocationResult allocation = AllocateEmptyFixedArray();
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_empty_fixed_array(FixedArray::cast(obj));
|
||||
|
||||
{
|
||||
AllocationResult allocation = Allocate(null_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_null_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kNull);
|
||||
|
||||
{
|
||||
AllocationResult allocation = Allocate(undefined_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_undefined_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kUndefined);
|
||||
DCHECK(!InNewSpace(undefined_value()));
|
||||
{
|
||||
AllocationResult allocation = Allocate(the_hole_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_the_hole_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kTheHole);
|
||||
|
||||
// Set preliminary exception sentinel value before actually initializing it.
|
||||
set_exception(null_value());
|
||||
|
||||
// Setup the struct maps first (needed for the EnumCache).
|
||||
for (unsigned i = 0; i < arraysize(struct_table); i++) {
|
||||
const StructTable& entry = struct_table[i];
|
||||
Map* map;
|
||||
if (!AllocatePartialMap(entry.type, entry.size).To(&map)) return false;
|
||||
roots_[entry.index] = map;
|
||||
}
|
||||
|
||||
// Allocate the empty enum cache.
|
||||
{
|
||||
AllocationResult allocation = Allocate(tuple2_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_empty_enum_cache(EnumCache::cast(obj));
|
||||
EnumCache::cast(obj)->set_keys(empty_fixed_array());
|
||||
EnumCache::cast(obj)->set_indices(empty_fixed_array());
|
||||
|
||||
// Allocate the empty descriptor array.
|
||||
{
|
||||
AllocationResult allocation =
|
||||
AllocateUninitializedFixedArray(DescriptorArray::kFirstIndex, TENURED);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_empty_descriptor_array(DescriptorArray::cast(obj));
|
||||
DescriptorArray::cast(obj)->set(DescriptorArray::kDescriptorLengthIndex,
|
||||
Smi::kZero);
|
||||
DescriptorArray::cast(obj)->set(DescriptorArray::kEnumCacheIndex,
|
||||
empty_enum_cache());
|
||||
|
||||
// Fix the instance_descriptors for the existing maps.
|
||||
FinalizePartialMap(this, meta_map());
|
||||
FinalizePartialMap(this, fixed_array_map());
|
||||
FinalizePartialMap(this, fixed_cow_array_map());
|
||||
FinalizePartialMap(this, undefined_map());
|
||||
undefined_map()->set_is_undetectable();
|
||||
FinalizePartialMap(this, null_map());
|
||||
null_map()->set_is_undetectable();
|
||||
FinalizePartialMap(this, the_hole_map());
|
||||
for (unsigned i = 0; i < arraysize(struct_table); ++i) {
|
||||
const StructTable& entry = struct_table[i];
|
||||
FinalizePartialMap(this, Map::cast(roots_[entry.index]));
|
||||
}
|
||||
|
||||
{ // Map allocation
|
||||
#define ALLOCATE_MAP(instance_type, size, field_name) \
|
||||
{ \
|
||||
Map* map; \
|
||||
if (!AllocateMap((instance_type), size).To(&map)) return false; \
|
||||
set_##field_name##_map(map); \
|
||||
}
|
||||
|
||||
#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
|
||||
ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
|
||||
|
||||
#define ALLOCATE_PRIMITIVE_MAP(instance_type, size, field_name, \
|
||||
constructor_function_index) \
|
||||
{ \
|
||||
ALLOCATE_MAP((instance_type), (size), field_name); \
|
||||
field_name##_map()->SetConstructorFunctionIndex( \
|
||||
(constructor_function_index)); \
|
||||
}
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
|
||||
ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector)
|
||||
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
|
||||
Context::NUMBER_FUNCTION_INDEX)
|
||||
ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
|
||||
mutable_heap_number)
|
||||
ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
|
||||
Context::SYMBOL_FUNCTION_INDEX)
|
||||
ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
|
||||
|
||||
ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean,
|
||||
Context::BOOLEAN_FUNCTION_INDEX);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register);
|
||||
|
||||
for (unsigned i = 0; i < arraysize(string_type_table); i++) {
|
||||
const StringTypeTable& entry = string_type_table[i];
|
||||
{
|
||||
AllocationResult allocation = AllocateMap(entry.type, entry.size);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
Map* map = Map::cast(obj);
|
||||
map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
|
||||
// Mark cons string maps as unstable, because their objects can change
|
||||
// maps during GC.
|
||||
if (StringShape(entry.type).IsCons()) map->mark_unstable();
|
||||
roots_[entry.index] = map;
|
||||
}
|
||||
|
||||
{ // Create a separate external one byte string map for native sources.
|
||||
AllocationResult allocation =
|
||||
AllocateMap(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE,
|
||||
ExternalOneByteString::kShortSize);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
Map* map = Map::cast(obj);
|
||||
map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
|
||||
set_native_source_string_map(map);
|
||||
}
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
|
||||
fixed_double_array_map()->set_elements_kind(HOLEY_DOUBLE_ELEMENTS);
|
||||
ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array)
|
||||
ALLOCATE_VARSIZE_MAP(BYTECODE_ARRAY_TYPE, bytecode_array)
|
||||
ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space)
|
||||
ALLOCATE_VARSIZE_MAP(PROPERTY_ARRAY_TYPE, property_array)
|
||||
ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_HASH_MAP_TYPE, small_ordered_hash_map)
|
||||
ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_HASH_SET_TYPE, small_ordered_hash_set)
|
||||
|
||||
#define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype, size) \
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array)
|
||||
|
||||
TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP)
|
||||
#undef ALLOCATE_FIXED_TYPED_ARRAY_MAP
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
|
||||
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell)
|
||||
ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
|
||||
ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, no_closures_cell)
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, one_closure_cell)
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, many_closures_cell)
|
||||
ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
|
||||
ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(TRANSITION_ARRAY_TYPE, transition_array)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, hash_table)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, ordered_hash_table)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, unseeded_number_dictionary)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, debug_evaluate_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, eval_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context_table)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context)
|
||||
native_context_map()->set_visitor_id(kVisitNativeContext);
|
||||
|
||||
ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
|
||||
shared_function_info)
|
||||
|
||||
ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
|
||||
ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
|
||||
external_map()->set_is_extensible(false);
|
||||
#undef ALLOCATE_PRIMITIVE_MAP
|
||||
#undef ALLOCATE_VARSIZE_MAP
|
||||
#undef ALLOCATE_MAP
|
||||
}
|
||||
|
||||
{
|
||||
AllocationResult allocation = AllocateEmptyScopeInfo();
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
|
||||
set_empty_scope_info(ScopeInfo::cast(obj));
|
||||
{
|
||||
AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_true_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kTrue);
|
||||
|
||||
{
|
||||
AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_false_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kFalse);
|
||||
|
||||
{ // Empty arrays
|
||||
{
|
||||
ByteArray* byte_array;
|
||||
if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false;
|
||||
set_empty_byte_array(byte_array);
|
||||
}
|
||||
|
||||
{
|
||||
PropertyArray* property_array;
|
||||
if (!AllocatePropertyArray(0, TENURED).To(&property_array)) return false;
|
||||
set_empty_property_array(property_array);
|
||||
}
|
||||
|
||||
#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
|
||||
{ \
|
||||
FixedTypedArrayBase* obj; \
|
||||
if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \
|
||||
return false; \
|
||||
set_empty_fixed_##type##_array(obj); \
|
||||
}
|
||||
|
||||
TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY)
|
||||
#undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY
|
||||
}
|
||||
DCHECK(!InNewSpace(empty_fixed_array()));
|
||||
return true;
|
||||
}
|
||||
|
||||
AllocationResult Heap::AllocateHeapNumber(MutableMode mode,
|
||||
PretenureFlag pretenure) {
|
||||
// Statically ensure that it is safe to allocate heap numbers in paged
|
||||
@ -2869,21 +2550,6 @@ AllocationResult Heap::AllocateTransitionArray(int capacity) {
|
||||
return array;
|
||||
}
|
||||
|
||||
bool Heap::CreateApiObjects() {
|
||||
HandleScope scope(isolate());
|
||||
set_message_listeners(*TemplateList::New(isolate(), 2));
|
||||
HeapObject* obj = nullptr;
|
||||
{
|
||||
AllocationResult allocation = AllocateStruct(INTERCEPTOR_INFO_TYPE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
InterceptorInfo* info = InterceptorInfo::cast(obj);
|
||||
info->set_flags(0);
|
||||
set_noop_interceptor_info(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Heap::CreateJSEntryStub() {
|
||||
JSEntryStub stub(isolate(), StackFrame::ENTRY);
|
||||
set_js_entry_code(*stub.GetCode());
|
||||
@ -2928,258 +2594,6 @@ void Heap::CreateFixedStubs() {
|
||||
Heap::CreateJSConstructEntryStub();
|
||||
}
|
||||
|
||||
|
||||
void Heap::CreateInitialObjects() {
|
||||
HandleScope scope(isolate());
|
||||
Factory* factory = isolate()->factory();
|
||||
|
||||
// The -0 value must be set before NewNumber works.
|
||||
set_minus_zero_value(*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED));
|
||||
DCHECK(std::signbit(minus_zero_value()->Number()) != 0);
|
||||
|
||||
set_nan_value(*factory->NewHeapNumber(
|
||||
std::numeric_limits<double>::quiet_NaN(), IMMUTABLE, TENURED));
|
||||
set_hole_nan_value(
|
||||
*factory->NewHeapNumberFromBits(kHoleNanInt64, IMMUTABLE, TENURED));
|
||||
set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED));
|
||||
set_minus_infinity_value(
|
||||
*factory->NewHeapNumber(-V8_INFINITY, IMMUTABLE, TENURED));
|
||||
|
||||
// Allocate initial string table.
|
||||
set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
|
||||
|
||||
// Allocate
|
||||
|
||||
// Finish initializing oddballs after creating the string table.
|
||||
Oddball::Initialize(isolate(), factory->undefined_value(), "undefined",
|
||||
factory->nan_value(), "undefined", Oddball::kUndefined);
|
||||
|
||||
// Initialize the null_value.
|
||||
Oddball::Initialize(isolate(), factory->null_value(), "null",
|
||||
handle(Smi::kZero, isolate()), "object", Oddball::kNull);
|
||||
|
||||
// Initialize the_hole_value.
|
||||
Oddball::Initialize(isolate(), factory->the_hole_value(), "hole",
|
||||
factory->hole_nan_value(), "undefined",
|
||||
Oddball::kTheHole);
|
||||
|
||||
// Initialize the true_value.
|
||||
Oddball::Initialize(isolate(), factory->true_value(), "true",
|
||||
handle(Smi::FromInt(1), isolate()), "boolean",
|
||||
Oddball::kTrue);
|
||||
|
||||
// Initialize the false_value.
|
||||
Oddball::Initialize(isolate(), factory->false_value(), "false",
|
||||
handle(Smi::kZero, isolate()), "boolean",
|
||||
Oddball::kFalse);
|
||||
|
||||
set_uninitialized_value(
|
||||
*factory->NewOddball(factory->uninitialized_map(), "uninitialized",
|
||||
handle(Smi::FromInt(-1), isolate()), "undefined",
|
||||
Oddball::kUninitialized));
|
||||
|
||||
set_arguments_marker(
|
||||
*factory->NewOddball(factory->arguments_marker_map(), "arguments_marker",
|
||||
handle(Smi::FromInt(-4), isolate()), "undefined",
|
||||
Oddball::kArgumentsMarker));
|
||||
|
||||
set_termination_exception(*factory->NewOddball(
|
||||
factory->termination_exception_map(), "termination_exception",
|
||||
handle(Smi::FromInt(-3), isolate()), "undefined", Oddball::kOther));
|
||||
|
||||
set_exception(*factory->NewOddball(factory->exception_map(), "exception",
|
||||
handle(Smi::FromInt(-5), isolate()),
|
||||
"undefined", Oddball::kException));
|
||||
|
||||
set_optimized_out(*factory->NewOddball(factory->optimized_out_map(),
|
||||
"optimized_out",
|
||||
handle(Smi::FromInt(-6), isolate()),
|
||||
"undefined", Oddball::kOptimizedOut));
|
||||
|
||||
set_stale_register(
|
||||
*factory->NewOddball(factory->stale_register_map(), "stale_register",
|
||||
handle(Smi::FromInt(-7), isolate()), "undefined",
|
||||
Oddball::kStaleRegister));
|
||||
|
||||
for (unsigned i = 0; i < arraysize(constant_string_table); i++) {
|
||||
Handle<String> str =
|
||||
factory->InternalizeUtf8String(constant_string_table[i].contents);
|
||||
roots_[constant_string_table[i].index] = *str;
|
||||
}
|
||||
|
||||
// Create the code_stubs dictionary. The initial size is set to avoid
|
||||
// expanding the dictionary during bootstrapping.
|
||||
set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
|
||||
|
||||
{
|
||||
HandleScope scope(isolate());
|
||||
#define SYMBOL_INIT(name) \
|
||||
{ \
|
||||
Handle<String> name##d = factory->NewStringFromStaticChars(#name); \
|
||||
Handle<Symbol> symbol(isolate()->factory()->NewPrivateSymbol()); \
|
||||
symbol->set_name(*name##d); \
|
||||
roots_[k##name##RootIndex] = *symbol; \
|
||||
}
|
||||
PRIVATE_SYMBOL_LIST(SYMBOL_INIT)
|
||||
#undef SYMBOL_INIT
|
||||
}
|
||||
|
||||
{
|
||||
HandleScope scope(isolate());
|
||||
#define SYMBOL_INIT(name, description) \
|
||||
Handle<Symbol> name = factory->NewSymbol(); \
|
||||
Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
|
||||
name->set_name(*name##d); \
|
||||
roots_[k##name##RootIndex] = *name;
|
||||
PUBLIC_SYMBOL_LIST(SYMBOL_INIT)
|
||||
#undef SYMBOL_INIT
|
||||
|
||||
#define SYMBOL_INIT(name, description) \
|
||||
Handle<Symbol> name = factory->NewSymbol(); \
|
||||
Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
|
||||
name->set_is_well_known_symbol(true); \
|
||||
name->set_name(*name##d); \
|
||||
roots_[k##name##RootIndex] = *name;
|
||||
WELL_KNOWN_SYMBOL_LIST(SYMBOL_INIT)
|
||||
#undef SYMBOL_INIT
|
||||
|
||||
// Mark "Interesting Symbols" appropriately.
|
||||
to_string_tag_symbol->set_is_interesting_symbol(true);
|
||||
}
|
||||
|
||||
Handle<NameDictionary> empty_property_dictionary =
|
||||
NameDictionary::New(isolate(), 1, TENURED, USE_CUSTOM_MINIMUM_CAPACITY);
|
||||
DCHECK(!empty_property_dictionary->HasSufficientCapacityToAdd(1));
|
||||
set_empty_property_dictionary(*empty_property_dictionary);
|
||||
|
||||
set_public_symbol_table(*empty_property_dictionary);
|
||||
set_api_symbol_table(*empty_property_dictionary);
|
||||
set_api_private_symbol_table(*empty_property_dictionary);
|
||||
|
||||
set_number_string_cache(
|
||||
*factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED));
|
||||
|
||||
// Allocate cache for single character one byte strings.
|
||||
set_single_character_string_cache(
|
||||
*factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED));
|
||||
|
||||
// Allocate cache for string split and regexp-multiple.
|
||||
set_string_split_cache(*factory->NewFixedArray(
|
||||
RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
|
||||
set_regexp_multiple_cache(*factory->NewFixedArray(
|
||||
RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
|
||||
|
||||
set_undefined_cell(*factory->NewCell(factory->undefined_value()));
|
||||
|
||||
// Microtask queue uses the empty fixed array as a sentinel for "empty".
|
||||
// Number of queued microtasks stored in Isolate::pending_microtask_count().
|
||||
set_microtask_queue(empty_fixed_array());
|
||||
|
||||
{
|
||||
Handle<FixedArray> empty_sloppy_arguments_elements =
|
||||
factory->NewFixedArray(2, TENURED);
|
||||
empty_sloppy_arguments_elements->set_map_after_allocation(
|
||||
sloppy_arguments_elements_map(), SKIP_WRITE_BARRIER);
|
||||
set_empty_sloppy_arguments_elements(*empty_sloppy_arguments_elements);
|
||||
}
|
||||
|
||||
{
|
||||
Handle<WeakCell> cell = factory->NewWeakCell(factory->undefined_value());
|
||||
set_empty_weak_cell(*cell);
|
||||
cell->clear();
|
||||
}
|
||||
|
||||
set_detached_contexts(empty_fixed_array());
|
||||
set_retained_maps(ArrayList::cast(empty_fixed_array()));
|
||||
set_retaining_path_targets(undefined_value());
|
||||
|
||||
set_weak_object_to_code_table(*WeakHashTable::New(isolate(), 16, TENURED));
|
||||
|
||||
set_weak_new_space_object_to_code_list(
|
||||
ArrayList::cast(*(factory->NewFixedArray(16, TENURED))));
|
||||
weak_new_space_object_to_code_list()->SetLength(0);
|
||||
|
||||
set_code_coverage_list(undefined_value());
|
||||
|
||||
set_script_list(Smi::kZero);
|
||||
|
||||
Handle<SeededNumberDictionary> slow_element_dictionary =
|
||||
SeededNumberDictionary::New(isolate(), 1, TENURED,
|
||||
USE_CUSTOM_MINIMUM_CAPACITY);
|
||||
DCHECK(!slow_element_dictionary->HasSufficientCapacityToAdd(1));
|
||||
slow_element_dictionary->set_requires_slow_elements();
|
||||
set_empty_slow_element_dictionary(*slow_element_dictionary);
|
||||
|
||||
set_materialized_objects(*factory->NewFixedArray(0, TENURED));
|
||||
|
||||
// Handling of script id generation is in Heap::NextScriptId().
|
||||
set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
|
||||
set_next_template_serial_number(Smi::kZero);
|
||||
|
||||
// Allocate the empty OrderedHashTable.
|
||||
Handle<FixedArray> empty_ordered_hash_table =
|
||||
factory->NewFixedArray(OrderedHashMap::kHashTableStartIndex, TENURED);
|
||||
empty_ordered_hash_table->set_map_no_write_barrier(
|
||||
*factory->ordered_hash_table_map());
|
||||
for (int i = 0; i < empty_ordered_hash_table->length(); ++i) {
|
||||
empty_ordered_hash_table->set(i, Smi::kZero);
|
||||
}
|
||||
set_empty_ordered_hash_table(*empty_ordered_hash_table);
|
||||
|
||||
// Allocate the empty script.
|
||||
Handle<Script> script = factory->NewScript(factory->empty_string());
|
||||
script->set_type(Script::TYPE_NATIVE);
|
||||
set_empty_script(*script);
|
||||
|
||||
Handle<PropertyCell> cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_array_protector(*cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(the_hole_value());
|
||||
set_empty_property_cell(*cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_array_iterator_protector(*cell);
|
||||
|
||||
Handle<Cell> is_concat_spreadable_cell = factory->NewCell(
|
||||
handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
|
||||
set_is_concat_spreadable_protector(*is_concat_spreadable_cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_species_protector(*cell);
|
||||
|
||||
Handle<Cell> string_length_overflow_cell = factory->NewCell(
|
||||
handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
|
||||
set_string_length_protector(*string_length_overflow_cell);
|
||||
|
||||
Handle<Cell> fast_array_iteration_cell = factory->NewCell(
|
||||
handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
|
||||
set_fast_array_iteration_protector(*fast_array_iteration_cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_array_buffer_neutering_protector(*cell);
|
||||
|
||||
set_serialized_templates(empty_fixed_array());
|
||||
set_serialized_global_proxy_sizes(empty_fixed_array());
|
||||
|
||||
set_weak_stack_trace_list(Smi::kZero);
|
||||
|
||||
set_noscript_shared_function_infos(Smi::kZero);
|
||||
|
||||
// Initialize context slot cache.
|
||||
isolate_->context_slot_cache()->Clear();
|
||||
|
||||
// Initialize descriptor cache.
|
||||
isolate_->descriptor_lookup_cache()->Clear();
|
||||
|
||||
// Initialize compilation cache.
|
||||
isolate_->compilation_cache()->Clear();
|
||||
}
|
||||
|
||||
bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
|
||||
switch (root_index) {
|
||||
case kNumberStringCacheRootIndex:
|
||||
@ -6072,22 +5486,6 @@ void Heap::InitializeHashSeed() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Heap::CreateHeapObjects() {
|
||||
// Create initial maps.
|
||||
if (!CreateInitialMaps()) return false;
|
||||
if (!CreateApiObjects()) return false;
|
||||
|
||||
// Create initial objects
|
||||
CreateInitialObjects();
|
||||
CHECK_EQ(0u, gc_count_);
|
||||
|
||||
set_native_contexts_list(undefined_value());
|
||||
set_allocation_sites_list(undefined_value());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Heap::SetStackLimits() {
|
||||
DCHECK(isolate_ != NULL);
|
||||
DCHECK(isolate_ == isolate());
|
||||
|
629
src/heap/setup-heap-internal.cc
Normal file
629
src/heap/setup-heap-internal.cc
Normal file
@ -0,0 +1,629 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
#include "src/setup-isolate.h"
|
||||
|
||||
#include "src/ast/context-slot-cache.h"
|
||||
#include "src/compilation-cache.h"
|
||||
#include "src/contexts.h"
|
||||
#include "src/factory.h"
|
||||
#include "src/heap-symbols.h"
|
||||
#include "src/heap/heap.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/layout-descriptor.h"
|
||||
#include "src/lookup-cache.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/arguments.h"
|
||||
#include "src/objects/debug-objects.h"
|
||||
#include "src/objects/descriptor-array.h"
|
||||
#include "src/objects/dictionary.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/module.h"
|
||||
#include "src/objects/script.h"
|
||||
#include "src/objects/shared-function-info.h"
|
||||
#include "src/objects/string.h"
|
||||
#include "src/regexp/jsregexp.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
bool SetupIsolateDelegate::SetupHeapInternal(Heap* heap) {
|
||||
return heap->CreateHeapObjects();
|
||||
}
|
||||
|
||||
bool Heap::CreateHeapObjects() {
|
||||
// Create initial maps.
|
||||
if (!CreateInitialMaps()) return false;
|
||||
if (!CreateApiObjects()) return false;
|
||||
|
||||
// Create initial objects
|
||||
CreateInitialObjects();
|
||||
CHECK_EQ(0u, gc_count_);
|
||||
|
||||
set_native_contexts_list(undefined_value());
|
||||
set_allocation_sites_list(undefined_value());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const Heap::StringTypeTable Heap::string_type_table[] = {
|
||||
#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
|
||||
{type, size, k##camel_name##MapRootIndex},
|
||||
STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
|
||||
#undef STRING_TYPE_ELEMENT
|
||||
};
|
||||
|
||||
const Heap::ConstantStringTable Heap::constant_string_table[] = {
|
||||
{"", kempty_stringRootIndex},
|
||||
#define CONSTANT_STRING_ELEMENT(name, contents) {contents, k##name##RootIndex},
|
||||
INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT)
|
||||
#undef CONSTANT_STRING_ELEMENT
|
||||
};
|
||||
|
||||
const Heap::StructTable Heap::struct_table[] = {
|
||||
#define STRUCT_TABLE_ELEMENT(NAME, Name, name) \
|
||||
{NAME##_TYPE, Name::kSize, k##Name##MapRootIndex},
|
||||
STRUCT_LIST(STRUCT_TABLE_ELEMENT)
|
||||
#undef STRUCT_TABLE_ELEMENT
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
void FinalizePartialMap(Heap* heap, Map* map) {
|
||||
map->set_code_cache(heap->empty_fixed_array());
|
||||
map->set_dependent_code(DependentCode::cast(heap->empty_fixed_array()));
|
||||
map->set_raw_transitions(Smi::kZero);
|
||||
map->set_instance_descriptors(heap->empty_descriptor_array());
|
||||
if (FLAG_unbox_double_fields) {
|
||||
map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
|
||||
}
|
||||
map->set_prototype(heap->null_value());
|
||||
map->set_constructor_or_backpointer(heap->null_value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Heap::CreateInitialMaps() {
|
||||
HeapObject* obj = nullptr;
|
||||
{
|
||||
AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
// Map::cast cannot be used due to uninitialized map field.
|
||||
Map* new_meta_map = reinterpret_cast<Map*>(obj);
|
||||
set_meta_map(new_meta_map);
|
||||
new_meta_map->set_map_after_allocation(new_meta_map);
|
||||
|
||||
{ // Partial map allocation
|
||||
#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \
|
||||
{ \
|
||||
Map* map; \
|
||||
if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \
|
||||
set_##field_name##_map(map); \
|
||||
}
|
||||
|
||||
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
|
||||
fixed_array_map()->set_elements_kind(HOLEY_ELEMENTS);
|
||||
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel,
|
||||
fixed_cow_array)
|
||||
fixed_cow_array_map()->set_elements_kind(HOLEY_ELEMENTS);
|
||||
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
|
||||
|
||||
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
|
||||
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
|
||||
ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
|
||||
|
||||
#undef ALLOCATE_PARTIAL_MAP
|
||||
}
|
||||
|
||||
// Allocate the empty array.
|
||||
{
|
||||
AllocationResult allocation = AllocateEmptyFixedArray();
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_empty_fixed_array(FixedArray::cast(obj));
|
||||
|
||||
{
|
||||
AllocationResult allocation = Allocate(null_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_null_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kNull);
|
||||
|
||||
{
|
||||
AllocationResult allocation = Allocate(undefined_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_undefined_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kUndefined);
|
||||
DCHECK(!InNewSpace(undefined_value()));
|
||||
{
|
||||
AllocationResult allocation = Allocate(the_hole_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_the_hole_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kTheHole);
|
||||
|
||||
// Set preliminary exception sentinel value before actually initializing it.
|
||||
set_exception(null_value());
|
||||
|
||||
// Setup the struct maps first (needed for the EnumCache).
|
||||
for (unsigned i = 0; i < arraysize(struct_table); i++) {
|
||||
const StructTable& entry = struct_table[i];
|
||||
Map* map;
|
||||
if (!AllocatePartialMap(entry.type, entry.size).To(&map)) return false;
|
||||
roots_[entry.index] = map;
|
||||
}
|
||||
|
||||
// Allocate the empty enum cache.
|
||||
{
|
||||
AllocationResult allocation = Allocate(tuple2_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_empty_enum_cache(EnumCache::cast(obj));
|
||||
EnumCache::cast(obj)->set_keys(empty_fixed_array());
|
||||
EnumCache::cast(obj)->set_indices(empty_fixed_array());
|
||||
|
||||
// Allocate the empty descriptor array.
|
||||
{
|
||||
AllocationResult allocation =
|
||||
AllocateUninitializedFixedArray(DescriptorArray::kFirstIndex, TENURED);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_empty_descriptor_array(DescriptorArray::cast(obj));
|
||||
DescriptorArray::cast(obj)->set(DescriptorArray::kDescriptorLengthIndex,
|
||||
Smi::kZero);
|
||||
DescriptorArray::cast(obj)->set(DescriptorArray::kEnumCacheIndex,
|
||||
empty_enum_cache());
|
||||
|
||||
// Fix the instance_descriptors for the existing maps.
|
||||
FinalizePartialMap(this, meta_map());
|
||||
FinalizePartialMap(this, fixed_array_map());
|
||||
FinalizePartialMap(this, fixed_cow_array_map());
|
||||
FinalizePartialMap(this, undefined_map());
|
||||
undefined_map()->set_is_undetectable();
|
||||
FinalizePartialMap(this, null_map());
|
||||
null_map()->set_is_undetectable();
|
||||
FinalizePartialMap(this, the_hole_map());
|
||||
for (unsigned i = 0; i < arraysize(struct_table); ++i) {
|
||||
const StructTable& entry = struct_table[i];
|
||||
FinalizePartialMap(this, Map::cast(roots_[entry.index]));
|
||||
}
|
||||
|
||||
{ // Map allocation
|
||||
#define ALLOCATE_MAP(instance_type, size, field_name) \
|
||||
{ \
|
||||
Map* map; \
|
||||
if (!AllocateMap((instance_type), size).To(&map)) return false; \
|
||||
set_##field_name##_map(map); \
|
||||
}
|
||||
|
||||
#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
|
||||
ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
|
||||
|
||||
#define ALLOCATE_PRIMITIVE_MAP(instance_type, size, field_name, \
|
||||
constructor_function_index) \
|
||||
{ \
|
||||
ALLOCATE_MAP((instance_type), (size), field_name); \
|
||||
field_name##_map()->SetConstructorFunctionIndex( \
|
||||
(constructor_function_index)); \
|
||||
}
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
|
||||
ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector)
|
||||
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
|
||||
Context::NUMBER_FUNCTION_INDEX)
|
||||
ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
|
||||
mutable_heap_number)
|
||||
ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
|
||||
Context::SYMBOL_FUNCTION_INDEX)
|
||||
ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
|
||||
|
||||
ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean,
|
||||
Context::BOOLEAN_FUNCTION_INDEX);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out);
|
||||
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register);
|
||||
|
||||
for (unsigned i = 0; i < arraysize(string_type_table); i++) {
|
||||
const StringTypeTable& entry = string_type_table[i];
|
||||
{
|
||||
AllocationResult allocation = AllocateMap(entry.type, entry.size);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
Map* map = Map::cast(obj);
|
||||
map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
|
||||
// Mark cons string maps as unstable, because their objects can change
|
||||
// maps during GC.
|
||||
if (StringShape(entry.type).IsCons()) map->mark_unstable();
|
||||
roots_[entry.index] = map;
|
||||
}
|
||||
|
||||
{ // Create a separate external one byte string map for native sources.
|
||||
AllocationResult allocation =
|
||||
AllocateMap(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE,
|
||||
ExternalOneByteString::kShortSize);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
Map* map = Map::cast(obj);
|
||||
map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
|
||||
set_native_source_string_map(map);
|
||||
}
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
|
||||
fixed_double_array_map()->set_elements_kind(HOLEY_DOUBLE_ELEMENTS);
|
||||
ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array)
|
||||
ALLOCATE_VARSIZE_MAP(BYTECODE_ARRAY_TYPE, bytecode_array)
|
||||
ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space)
|
||||
ALLOCATE_VARSIZE_MAP(PROPERTY_ARRAY_TYPE, property_array)
|
||||
ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_HASH_MAP_TYPE, small_ordered_hash_map)
|
||||
ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_HASH_SET_TYPE, small_ordered_hash_set)
|
||||
|
||||
#define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype, size) \
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array)
|
||||
|
||||
TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP)
|
||||
#undef ALLOCATE_FIXED_TYPED_ARRAY_MAP
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
|
||||
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell)
|
||||
ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
|
||||
ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, no_closures_cell)
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, one_closure_cell)
|
||||
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, many_closures_cell)
|
||||
ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
|
||||
ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(TRANSITION_ARRAY_TYPE, transition_array)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, hash_table)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, ordered_hash_table)
|
||||
ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, unseeded_number_dictionary)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, debug_evaluate_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, eval_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context_table)
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context)
|
||||
native_context_map()->set_visitor_id(kVisitNativeContext);
|
||||
|
||||
ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
|
||||
shared_function_info)
|
||||
|
||||
ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
|
||||
ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
|
||||
external_map()->set_is_extensible(false);
|
||||
#undef ALLOCATE_PRIMITIVE_MAP
|
||||
#undef ALLOCATE_VARSIZE_MAP
|
||||
#undef ALLOCATE_MAP
|
||||
}
|
||||
|
||||
{
|
||||
AllocationResult allocation = AllocateEmptyScopeInfo();
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
|
||||
set_empty_scope_info(ScopeInfo::cast(obj));
|
||||
{
|
||||
AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_true_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kTrue);
|
||||
|
||||
{
|
||||
AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
set_false_value(Oddball::cast(obj));
|
||||
Oddball::cast(obj)->set_kind(Oddball::kFalse);
|
||||
|
||||
{ // Empty arrays
|
||||
{
|
||||
ByteArray * byte_array;
|
||||
if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false;
|
||||
set_empty_byte_array(byte_array);
|
||||
}
|
||||
|
||||
{
|
||||
PropertyArray* property_array;
|
||||
if (!AllocatePropertyArray(0, TENURED).To(&property_array)) return false;
|
||||
set_empty_property_array(property_array);
|
||||
}
|
||||
|
||||
#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
|
||||
{ \
|
||||
FixedTypedArrayBase* obj; \
|
||||
if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \
|
||||
return false; \
|
||||
set_empty_fixed_##type##_array(obj); \
|
||||
}
|
||||
|
||||
TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY)
|
||||
#undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY
|
||||
}
|
||||
DCHECK(!InNewSpace(empty_fixed_array()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Heap::CreateApiObjects() {
|
||||
HandleScope scope(isolate());
|
||||
set_message_listeners(*TemplateList::New(isolate(), 2));
|
||||
HeapObject* obj = nullptr;
|
||||
{
|
||||
AllocationResult allocation = AllocateStruct(INTERCEPTOR_INFO_TYPE);
|
||||
if (!allocation.To(&obj)) return false;
|
||||
}
|
||||
InterceptorInfo* info = InterceptorInfo::cast(obj);
|
||||
info->set_flags(0);
|
||||
set_noop_interceptor_info(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Heap::CreateInitialObjects() {
|
||||
HandleScope scope(isolate());
|
||||
Factory* factory = isolate()->factory();
|
||||
|
||||
// The -0 value must be set before NewNumber works.
|
||||
set_minus_zero_value(*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED));
|
||||
DCHECK(std::signbit(minus_zero_value()->Number()) != 0);
|
||||
|
||||
set_nan_value(*factory->NewHeapNumber(
|
||||
std::numeric_limits<double>::quiet_NaN(), IMMUTABLE, TENURED));
|
||||
set_hole_nan_value(
|
||||
*factory->NewHeapNumberFromBits(kHoleNanInt64, IMMUTABLE, TENURED));
|
||||
set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED));
|
||||
set_minus_infinity_value(
|
||||
*factory->NewHeapNumber(-V8_INFINITY, IMMUTABLE, TENURED));
|
||||
|
||||
// Allocate initial string table.
|
||||
set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
|
||||
|
||||
// Allocate
|
||||
|
||||
// Finish initializing oddballs after creating the string table.
|
||||
Oddball::Initialize(isolate(), factory->undefined_value(), "undefined",
|
||||
factory->nan_value(), "undefined", Oddball::kUndefined);
|
||||
|
||||
// Initialize the null_value.
|
||||
Oddball::Initialize(isolate(), factory->null_value(), "null",
|
||||
handle(Smi::kZero, isolate()), "object", Oddball::kNull);
|
||||
|
||||
// Initialize the_hole_value.
|
||||
Oddball::Initialize(isolate(), factory->the_hole_value(), "hole",
|
||||
factory->hole_nan_value(), "undefined",
|
||||
Oddball::kTheHole);
|
||||
|
||||
// Initialize the true_value.
|
||||
Oddball::Initialize(isolate(), factory->true_value(), "true",
|
||||
handle(Smi::FromInt(1), isolate()), "boolean",
|
||||
Oddball::kTrue);
|
||||
|
||||
// Initialize the false_value.
|
||||
Oddball::Initialize(isolate(), factory->false_value(), "false",
|
||||
handle(Smi::kZero, isolate()), "boolean",
|
||||
Oddball::kFalse);
|
||||
|
||||
set_uninitialized_value(
|
||||
*factory->NewOddball(factory->uninitialized_map(), "uninitialized",
|
||||
handle(Smi::FromInt(-1), isolate()), "undefined",
|
||||
Oddball::kUninitialized));
|
||||
|
||||
set_arguments_marker(
|
||||
*factory->NewOddball(factory->arguments_marker_map(), "arguments_marker",
|
||||
handle(Smi::FromInt(-4), isolate()), "undefined",
|
||||
Oddball::kArgumentsMarker));
|
||||
|
||||
set_termination_exception(*factory->NewOddball(
|
||||
factory->termination_exception_map(), "termination_exception",
|
||||
handle(Smi::FromInt(-3), isolate()), "undefined", Oddball::kOther));
|
||||
|
||||
set_exception(*factory->NewOddball(factory->exception_map(), "exception",
|
||||
handle(Smi::FromInt(-5), isolate()),
|
||||
"undefined", Oddball::kException));
|
||||
|
||||
set_optimized_out(*factory->NewOddball(factory->optimized_out_map(),
|
||||
"optimized_out",
|
||||
handle(Smi::FromInt(-6), isolate()),
|
||||
"undefined", Oddball::kOptimizedOut));
|
||||
|
||||
set_stale_register(
|
||||
*factory->NewOddball(factory->stale_register_map(), "stale_register",
|
||||
handle(Smi::FromInt(-7), isolate()), "undefined",
|
||||
Oddball::kStaleRegister));
|
||||
|
||||
for (unsigned i = 0; i < arraysize(constant_string_table); i++) {
|
||||
Handle<String> str =
|
||||
factory->InternalizeUtf8String(constant_string_table[i].contents);
|
||||
roots_[constant_string_table[i].index] = *str;
|
||||
}
|
||||
|
||||
// Create the code_stubs dictionary. The initial size is set to avoid
|
||||
// expanding the dictionary during bootstrapping.
|
||||
set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
|
||||
|
||||
{
|
||||
HandleScope scope(isolate());
|
||||
#define SYMBOL_INIT(name) \
|
||||
{ \
|
||||
Handle<String> name##d = factory->NewStringFromStaticChars(#name); \
|
||||
Handle<Symbol> symbol(isolate()->factory()->NewPrivateSymbol()); \
|
||||
symbol->set_name(*name##d); \
|
||||
roots_[k##name##RootIndex] = *symbol; \
|
||||
}
|
||||
PRIVATE_SYMBOL_LIST(SYMBOL_INIT)
|
||||
#undef SYMBOL_INIT
|
||||
}
|
||||
|
||||
{
|
||||
HandleScope scope(isolate());
|
||||
#define SYMBOL_INIT(name, description) \
|
||||
Handle<Symbol> name = factory->NewSymbol(); \
|
||||
Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
|
||||
name->set_name(*name##d); \
|
||||
roots_[k##name##RootIndex] = *name;
|
||||
PUBLIC_SYMBOL_LIST(SYMBOL_INIT)
|
||||
#undef SYMBOL_INIT
|
||||
|
||||
#define SYMBOL_INIT(name, description) \
|
||||
Handle<Symbol> name = factory->NewSymbol(); \
|
||||
Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
|
||||
name->set_is_well_known_symbol(true); \
|
||||
name->set_name(*name##d); \
|
||||
roots_[k##name##RootIndex] = *name;
|
||||
WELL_KNOWN_SYMBOL_LIST(SYMBOL_INIT)
|
||||
#undef SYMBOL_INIT
|
||||
|
||||
// Mark "Interesting Symbols" appropriately.
|
||||
to_string_tag_symbol->set_is_interesting_symbol(true);
|
||||
}
|
||||
|
||||
Handle<NameDictionary> empty_property_dictionary =
|
||||
NameDictionary::New(isolate(), 1, TENURED, USE_CUSTOM_MINIMUM_CAPACITY);
|
||||
DCHECK(!empty_property_dictionary->HasSufficientCapacityToAdd(1));
|
||||
set_empty_property_dictionary(*empty_property_dictionary);
|
||||
|
||||
set_public_symbol_table(*empty_property_dictionary);
|
||||
set_api_symbol_table(*empty_property_dictionary);
|
||||
set_api_private_symbol_table(*empty_property_dictionary);
|
||||
|
||||
set_number_string_cache(
|
||||
*factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED));
|
||||
|
||||
// Allocate cache for single character one byte strings.
|
||||
set_single_character_string_cache(
|
||||
*factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED));
|
||||
|
||||
// Allocate cache for string split and regexp-multiple.
|
||||
set_string_split_cache(*factory->NewFixedArray(
|
||||
RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
|
||||
set_regexp_multiple_cache(*factory->NewFixedArray(
|
||||
RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
|
||||
|
||||
set_undefined_cell(*factory->NewCell(factory->undefined_value()));
|
||||
|
||||
// Microtask queue uses the empty fixed array as a sentinel for "empty".
|
||||
// Number of queued microtasks stored in Isolate::pending_microtask_count().
|
||||
set_microtask_queue(empty_fixed_array());
|
||||
|
||||
{
|
||||
Handle<FixedArray> empty_sloppy_arguments_elements =
|
||||
factory->NewFixedArray(2, TENURED);
|
||||
empty_sloppy_arguments_elements->set_map_after_allocation(
|
||||
sloppy_arguments_elements_map(), SKIP_WRITE_BARRIER);
|
||||
set_empty_sloppy_arguments_elements(*empty_sloppy_arguments_elements);
|
||||
}
|
||||
|
||||
{
|
||||
Handle<WeakCell> cell = factory->NewWeakCell(factory->undefined_value());
|
||||
set_empty_weak_cell(*cell);
|
||||
cell->clear();
|
||||
}
|
||||
|
||||
set_detached_contexts(empty_fixed_array());
|
||||
set_retained_maps(ArrayList::cast(empty_fixed_array()));
|
||||
set_retaining_path_targets(undefined_value());
|
||||
|
||||
set_weak_object_to_code_table(*WeakHashTable::New(isolate(), 16, TENURED));
|
||||
|
||||
set_weak_new_space_object_to_code_list(
|
||||
ArrayList::cast(*(factory->NewFixedArray(16, TENURED))));
|
||||
weak_new_space_object_to_code_list()->SetLength(0);
|
||||
|
||||
set_code_coverage_list(undefined_value());
|
||||
|
||||
set_script_list(Smi::kZero);
|
||||
|
||||
Handle<SeededNumberDictionary> slow_element_dictionary =
|
||||
SeededNumberDictionary::New(isolate(), 1, TENURED,
|
||||
USE_CUSTOM_MINIMUM_CAPACITY);
|
||||
DCHECK(!slow_element_dictionary->HasSufficientCapacityToAdd(1));
|
||||
slow_element_dictionary->set_requires_slow_elements();
|
||||
set_empty_slow_element_dictionary(*slow_element_dictionary);
|
||||
|
||||
set_materialized_objects(*factory->NewFixedArray(0, TENURED));
|
||||
|
||||
// Handling of script id generation is in Heap::NextScriptId().
|
||||
set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
|
||||
set_next_template_serial_number(Smi::kZero);
|
||||
|
||||
// Allocate the empty OrderedHashTable.
|
||||
Handle<FixedArray> empty_ordered_hash_table =
|
||||
factory->NewFixedArray(OrderedHashMap::kHashTableStartIndex, TENURED);
|
||||
empty_ordered_hash_table->set_map_no_write_barrier(
|
||||
*factory->ordered_hash_table_map());
|
||||
for (int i = 0; i < empty_ordered_hash_table->length(); ++i) {
|
||||
empty_ordered_hash_table->set(i, Smi::kZero);
|
||||
}
|
||||
set_empty_ordered_hash_table(*empty_ordered_hash_table);
|
||||
|
||||
// Allocate the empty script.
|
||||
Handle<Script> script = factory->NewScript(factory->empty_string());
|
||||
script->set_type(Script::TYPE_NATIVE);
|
||||
set_empty_script(*script);
|
||||
|
||||
Handle<PropertyCell> cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_array_protector(*cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(the_hole_value());
|
||||
set_empty_property_cell(*cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_array_iterator_protector(*cell);
|
||||
|
||||
Handle<Cell> is_concat_spreadable_cell = factory->NewCell(
|
||||
handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
|
||||
set_is_concat_spreadable_protector(*is_concat_spreadable_cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_species_protector(*cell);
|
||||
|
||||
Handle<Cell> string_length_overflow_cell = factory->NewCell(
|
||||
handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
|
||||
set_string_length_protector(*string_length_overflow_cell);
|
||||
|
||||
Handle<Cell> fast_array_iteration_cell = factory->NewCell(
|
||||
handle(Smi::FromInt(Isolate::kProtectorValid), isolate()));
|
||||
set_fast_array_iteration_protector(*fast_array_iteration_cell);
|
||||
|
||||
cell = factory->NewPropertyCell(factory->empty_string());
|
||||
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
|
||||
set_array_buffer_neutering_protector(*cell);
|
||||
|
||||
set_serialized_templates(empty_fixed_array());
|
||||
set_serialized_global_proxy_sizes(empty_fixed_array());
|
||||
|
||||
set_weak_stack_trace_list(Smi::kZero);
|
||||
|
||||
set_noscript_shared_function_infos(Smi::kZero);
|
||||
|
||||
// Initialize context slot cache.
|
||||
isolate_->context_slot_cache()->Clear();
|
||||
|
||||
// Initialize descriptor cache.
|
||||
isolate_->descriptor_lookup_cache()->Clear();
|
||||
|
||||
// Initialize compilation cache.
|
||||
isolate_->compilation_cache()->Clear();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -2775,7 +2775,11 @@ bool Isolate::Init(StartupDeserializer* des) {
|
||||
deoptimizer_data_ = new DeoptimizerData(heap()->memory_allocator());
|
||||
|
||||
const bool create_heap_objects = (des == NULL);
|
||||
if (create_heap_objects && !heap_.CreateHeapObjects()) {
|
||||
if (setup_delegate_ == nullptr) {
|
||||
setup_delegate_ = new SetupIsolateDelegate(create_heap_objects);
|
||||
}
|
||||
|
||||
if (!setup_delegate_->SetupHeap(&heap_)) {
|
||||
V8::FatalProcessOutOfMemory("heap object creation");
|
||||
return false;
|
||||
}
|
||||
@ -2788,10 +2792,7 @@ bool Isolate::Init(StartupDeserializer* des) {
|
||||
InitializeThreadLocal();
|
||||
|
||||
bootstrapper_->Initialize(create_heap_objects);
|
||||
if (setup_delegate_ == nullptr) {
|
||||
setup_delegate_ = new SetupIsolateDelegate();
|
||||
}
|
||||
setup_delegate_->SetupBuiltins(this, create_heap_objects);
|
||||
setup_delegate_->SetupBuiltins(this);
|
||||
if (create_heap_objects) heap_.CreateFixedStubs();
|
||||
|
||||
if (FLAG_log_internal_timer_events) {
|
||||
@ -2815,7 +2816,7 @@ bool Isolate::Init(StartupDeserializer* des) {
|
||||
if (!create_heap_objects) des->DeserializeInto(this);
|
||||
load_stub_cache_->Initialize();
|
||||
store_stub_cache_->Initialize();
|
||||
setup_delegate_->SetupInterpreter(interpreter_, create_heap_objects);
|
||||
setup_delegate_->SetupInterpreter(interpreter_);
|
||||
|
||||
heap_.NotifyDeserializationComplete();
|
||||
}
|
||||
|
@ -12,14 +12,13 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate,
|
||||
bool create_heap_objects) {
|
||||
DCHECK(!create_heap_objects);
|
||||
void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate) {
|
||||
DCHECK(!create_heap_objects_);
|
||||
// No actual work to be done; builtins will be deserialized from the snapshot.
|
||||
}
|
||||
|
||||
void SetupIsolateDelegate::SetupInterpreter(
|
||||
interpreter::Interpreter* interpreter, bool create_heap_objects) {
|
||||
interpreter::Interpreter* interpreter) {
|
||||
#if defined(V8_USE_SNAPSHOT) && !defined(V8_USE_SNAPSHOT_WITH_UNWINDING_INFO)
|
||||
if (FLAG_perf_prof_unwinding_info) {
|
||||
OFStream os(stdout);
|
||||
@ -31,5 +30,11 @@ void SetupIsolateDelegate::SetupInterpreter(
|
||||
DCHECK(interpreter->IsDispatchTableInitialized());
|
||||
}
|
||||
|
||||
bool SetupIsolateDelegate::SetupHeap(Heap* heap) {
|
||||
DCHECK(!create_heap_objects_);
|
||||
// No actual work to be done; heap will be deserialized from the snapshot.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/setup-isolate.h"
|
||||
|
||||
#include "src/base/logging.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/interpreter/interpreter.h"
|
||||
#include "src/interpreter/setup-interpreter.h"
|
||||
#include "src/isolate.h"
|
||||
@ -12,9 +13,8 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate,
|
||||
bool create_heap_objects) {
|
||||
if (create_heap_objects) {
|
||||
void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate) {
|
||||
if (create_heap_objects_) {
|
||||
SetupBuiltinsInternal(isolate);
|
||||
} else {
|
||||
DCHECK(isolate->snapshot_available());
|
||||
@ -22,13 +22,22 @@ void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate,
|
||||
}
|
||||
|
||||
void SetupIsolateDelegate::SetupInterpreter(
|
||||
interpreter::Interpreter* interpreter, bool create_heap_objects) {
|
||||
if (create_heap_objects) {
|
||||
interpreter::Interpreter* interpreter) {
|
||||
if (create_heap_objects_) {
|
||||
interpreter::SetupInterpreter::InstallBytecodeHandlers(interpreter);
|
||||
} else {
|
||||
DCHECK(interpreter->IsDispatchTableInitialized());
|
||||
}
|
||||
}
|
||||
|
||||
bool SetupIsolateDelegate::SetupHeap(Heap* heap) {
|
||||
if (create_heap_objects_) {
|
||||
return SetupHeapInternal(heap);
|
||||
} else {
|
||||
DCHECK(heap->isolate()->snapshot_available());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -10,6 +10,7 @@ namespace internal {
|
||||
|
||||
class Builtins;
|
||||
class Code;
|
||||
class Heap;
|
||||
class Isolate;
|
||||
|
||||
namespace interpreter {
|
||||
@ -31,19 +32,25 @@ class Interpreter;
|
||||
// linked in by the latter two Delegate implementations.
|
||||
class SetupIsolateDelegate {
|
||||
public:
|
||||
SetupIsolateDelegate() {}
|
||||
explicit SetupIsolateDelegate(bool create_heap_objects)
|
||||
: create_heap_objects_(create_heap_objects) {}
|
||||
virtual ~SetupIsolateDelegate() {}
|
||||
|
||||
virtual void SetupBuiltins(Isolate* isolate, bool create_heap_objects);
|
||||
virtual void SetupBuiltins(Isolate* isolate);
|
||||
|
||||
virtual void SetupInterpreter(interpreter::Interpreter* interpreter,
|
||||
bool create_heap_objects);
|
||||
virtual void SetupInterpreter(interpreter::Interpreter* interpreter);
|
||||
|
||||
virtual bool SetupHeap(Heap* heap);
|
||||
|
||||
protected:
|
||||
static void SetupBuiltinsInternal(Isolate* isolate);
|
||||
static void AddBuiltin(Builtins* builtins, int index, Code* code);
|
||||
static void PopulateWithPlaceholders(Isolate* isolate);
|
||||
static void ReplacePlaceholders(Isolate* isolate);
|
||||
|
||||
static bool SetupHeapInternal(Heap* heap);
|
||||
|
||||
const bool create_heap_objects_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
11
src/v8.gyp
11
src/v8.gyp
@ -99,7 +99,7 @@
|
||||
# The dependency on v8_base should come from a transitive
|
||||
# dependency however the Android toolchain requires libv8_base.a
|
||||
# to appear before libv8_snapshot.a so it's listed explicitly.
|
||||
'dependencies': ['v8_base', 'v8_builtins_setup', 'v8_nosnapshot'],
|
||||
'dependencies': ['v8_base', 'v8_init', 'v8_nosnapshot'],
|
||||
}],
|
||||
['v8_use_snapshot=="true" and v8_use_external_startup_data==0', {
|
||||
# The dependency on v8_base should come from a transitive
|
||||
@ -133,10 +133,10 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'v8_builtins_setup',
|
||||
'target_name': 'v8_init',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'v8_builtins_generators',
|
||||
'v8_initializers',
|
||||
],
|
||||
'variables': {
|
||||
'optimize': 'max',
|
||||
@ -157,7 +157,7 @@
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'v8_builtins_generators',
|
||||
'target_name': 'v8_initializers',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'v8_base',
|
||||
@ -216,6 +216,7 @@
|
||||
'builtins/builtins-utils-gen.h',
|
||||
'builtins/builtins-wasm-gen.cc',
|
||||
'builtins/setup-builtins-internal.cc',
|
||||
'heap/setup-heap-internal.cc',
|
||||
'ic/accessor-assembler.cc',
|
||||
'ic/accessor-assembler.h',
|
||||
'ic/binary-op-assembler.cc',
|
||||
@ -2469,7 +2470,7 @@
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'v8_base',
|
||||
'v8_builtins_setup',
|
||||
'v8_init',
|
||||
'v8_libbase',
|
||||
'v8_libplatform',
|
||||
'v8_nosnapshot',
|
||||
|
@ -326,7 +326,7 @@ v8_executable("cctest") {
|
||||
|
||||
deps = [
|
||||
":resources",
|
||||
"../..:v8_builtins_generators",
|
||||
"../..:v8_initializers",
|
||||
"../..:v8_libbase",
|
||||
"../..:v8_libplatform",
|
||||
"../..:wasm_module_runner",
|
||||
|
@ -433,7 +433,7 @@
|
||||
'dependencies': ['../../src/v8.gyp:v8'],
|
||||
}],
|
||||
['v8_use_snapshot=="true"', {
|
||||
'dependencies': ['../../src/v8.gyp:v8_builtins_generators'],
|
||||
'dependencies': ['../../src/v8.gyp:v8_initializers'],
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
@ -9,19 +9,25 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void SetupIsolateDelegateForTests::SetupBuiltins(Isolate* isolate,
|
||||
bool create_heap_objects) {
|
||||
if (create_heap_objects) {
|
||||
void SetupIsolateDelegateForTests::SetupBuiltins(Isolate* isolate) {
|
||||
if (create_heap_objects_) {
|
||||
SetupBuiltinsInternal(isolate);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupIsolateDelegateForTests::SetupInterpreter(
|
||||
interpreter::Interpreter* interpreter, bool create_heap_objects) {
|
||||
if (create_heap_objects) {
|
||||
interpreter::Interpreter* interpreter) {
|
||||
if (create_heap_objects_) {
|
||||
interpreter::SetupInterpreter::InstallBytecodeHandlers(interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
bool SetupIsolateDelegateForTests::SetupHeap(Heap* heap) {
|
||||
if (create_heap_objects_) {
|
||||
return SetupHeapInternal(heap);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -12,13 +12,15 @@ namespace internal {
|
||||
|
||||
class SetupIsolateDelegateForTests : public SetupIsolateDelegate {
|
||||
public:
|
||||
SetupIsolateDelegateForTests() : SetupIsolateDelegate() {}
|
||||
explicit SetupIsolateDelegateForTests(bool create_heap_objects)
|
||||
: SetupIsolateDelegate(create_heap_objects) {}
|
||||
virtual ~SetupIsolateDelegateForTests() {}
|
||||
|
||||
void SetupBuiltins(Isolate* isolate, bool create_heap_objects) override;
|
||||
void SetupBuiltins(Isolate* isolate) override;
|
||||
|
||||
void SetupInterpreter(interpreter::Interpreter* interpreter,
|
||||
bool create_heap_objects) override;
|
||||
void SetupInterpreter(interpreter::Interpreter* interpreter) override;
|
||||
|
||||
bool SetupHeap(Heap* heap) override;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -69,7 +69,7 @@ class TestIsolate : public Isolate {
|
||||
public:
|
||||
static v8::Isolate* NewInitialized(bool enable_serializer) {
|
||||
i::Isolate* isolate = new TestIsolate(enable_serializer);
|
||||
isolate->setup_delegate_ = new SetupIsolateDelegateForTests();
|
||||
isolate->setup_delegate_ = new SetupIsolateDelegateForTests(true);
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
isolate->Init(NULL);
|
||||
@ -80,14 +80,16 @@ class TestIsolate : public Isolate {
|
||||
// the production Isolate class has one or the other behavior baked in.
|
||||
static v8::Isolate* New(const v8::Isolate::CreateParams& params) {
|
||||
i::Isolate* isolate = new TestIsolate(false);
|
||||
isolate->setup_delegate_ = new SetupIsolateDelegateForTests();
|
||||
bool create_heap_objects = params.snapshot_blob == nullptr;
|
||||
isolate->setup_delegate_ =
|
||||
new SetupIsolateDelegateForTests(create_heap_objects);
|
||||
return v8::IsolateNewImpl(isolate, params);
|
||||
}
|
||||
explicit TestIsolate(bool enable_serializer) : Isolate(enable_serializer) {
|
||||
set_array_buffer_allocator(CcTest::array_buffer_allocator());
|
||||
}
|
||||
void CreateSetupDelegateForTests() {
|
||||
setup_delegate_ = new SetupIsolateDelegateForTests();
|
||||
void SetDeserializeFromSnapshot() {
|
||||
setup_delegate_ = new SetupIsolateDelegateForTests(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -164,7 +166,7 @@ v8::Isolate* InitializeFromBlob(StartupBlobs& blobs) {
|
||||
TestIsolate* isolate = new TestIsolate(false);
|
||||
v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
isolate->CreateSetupDelegateForTests();
|
||||
isolate->SetDeserializeFromSnapshot();
|
||||
isolate->Init(&deserializer);
|
||||
}
|
||||
return v8_isolate;
|
||||
|
@ -266,7 +266,7 @@
|
||||
],
|
||||
}],
|
||||
['v8_use_snapshot=="true"', {
|
||||
'dependencies': ['../../src/v8.gyp:v8_builtins_generators'],
|
||||
'dependencies': ['../../src/v8.gyp:v8_initializers'],
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user