📄 heap.cc.svn-base
字号:
// Record the object's address at the top of the to space, to allow // it to be swept by the scavenger. promoted_top -= kPointerSize; Memory::Object_at(promoted_top) = *p; } else {#ifdef DEBUG // Objects promoted to the data space should not have pointers to // new space. VerifyNonPointerSpacePointersVisitor v; (*p)->Iterate(&v);#endif } return; } } // The object should remain in new space or the old space allocation failed. result = new_space_->AllocateRaw(object_size); // Failed allocation at this point is utterly unexpected. ASSERT(!result->IsFailure()); *p = MigrateObject(p, HeapObject::cast(result), object_size);}Object* Heap::AllocatePartialMap(InstanceType instance_type, int instance_size) { Object* result = AllocateRawMap(Map::kSize); if (result->IsFailure()) return result; // Map::cast cannot be used due to uninitialized map field. reinterpret_cast<Map*>(result)->set_map(meta_map()); reinterpret_cast<Map*>(result)->set_instance_type(instance_type); reinterpret_cast<Map*>(result)->set_instance_size(instance_size); reinterpret_cast<Map*>(result)->set_unused_property_fields(0); return result;}Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) { Object* result = AllocateRawMap(Map::kSize); if (result->IsFailure()) return result; Map* map = reinterpret_cast<Map*>(result); map->set_map(meta_map()); map->set_instance_type(instance_type); map->set_prototype(null_value()); map->set_constructor(null_value()); map->set_instance_size(instance_size); map->set_instance_descriptors(empty_descriptor_array()); map->set_code_cache(empty_fixed_array()); map->set_unused_property_fields(0); map->set_bit_field(0); return map;}bool Heap::CreateInitialMaps() { Object* obj = AllocatePartialMap(MAP_TYPE, Map::kSize); if (obj->IsFailure()) return false; // Map::cast cannot be used due to uninitialized map field. meta_map_ = reinterpret_cast<Map*>(obj); meta_map()->set_map(meta_map()); obj = AllocatePartialMap(FIXED_ARRAY_TYPE, Array::kHeaderSize); if (obj->IsFailure()) return false; fixed_array_map_ = Map::cast(obj); obj = AllocatePartialMap(ODDBALL_TYPE, Oddball::kSize); if (obj->IsFailure()) return false; oddball_map_ = Map::cast(obj); // Allocate the empty array obj = AllocateEmptyFixedArray(); if (obj->IsFailure()) return false; empty_fixed_array_ = FixedArray::cast(obj); obj = Allocate(oddball_map(), OLD_DATA_SPACE); if (obj->IsFailure()) return false; null_value_ = obj; // Allocate the empty descriptor array. AllocateMap can now be used. obj = AllocateEmptyFixedArray(); if (obj->IsFailure()) return false; // There is a check against empty_descriptor_array() in cast(). empty_descriptor_array_ = reinterpret_cast<DescriptorArray*>(obj); // Fix the instance_descriptors for the existing maps. meta_map()->set_instance_descriptors(empty_descriptor_array()); meta_map()->set_code_cache(empty_fixed_array()); fixed_array_map()->set_instance_descriptors(empty_descriptor_array()); fixed_array_map()->set_code_cache(empty_fixed_array()); oddball_map()->set_instance_descriptors(empty_descriptor_array()); oddball_map()->set_code_cache(empty_fixed_array()); // Fix prototype object for existing maps. meta_map()->set_prototype(null_value()); meta_map()->set_constructor(null_value()); fixed_array_map()->set_prototype(null_value()); fixed_array_map()->set_constructor(null_value()); oddball_map()->set_prototype(null_value()); oddball_map()->set_constructor(null_value()); obj = AllocateMap(HEAP_NUMBER_TYPE, HeapNumber::kSize); if (obj->IsFailure()) return false; heap_number_map_ = Map::cast(obj); obj = AllocateMap(PROXY_TYPE, Proxy::kSize); if (obj->IsFailure()) return false; proxy_map_ = Map::cast(obj);#define ALLOCATE_STRING_MAP(type, size, name) \ obj = AllocateMap(type, size); \ if (obj->IsFailure()) return false; \ name##_map_ = Map::cast(obj); STRING_TYPE_LIST(ALLOCATE_STRING_MAP);#undef ALLOCATE_STRING_MAP obj = AllocateMap(SHORT_STRING_TYPE, TwoByteString::kHeaderSize); if (obj->IsFailure()) return false; undetectable_short_string_map_ = Map::cast(obj); undetectable_short_string_map_->set_is_undetectable(); obj = AllocateMap(MEDIUM_STRING_TYPE, TwoByteString::kHeaderSize); if (obj->IsFailure()) return false; undetectable_medium_string_map_ = Map::cast(obj); undetectable_medium_string_map_->set_is_undetectable(); obj = AllocateMap(LONG_STRING_TYPE, TwoByteString::kHeaderSize); if (obj->IsFailure()) return false; undetectable_long_string_map_ = Map::cast(obj); undetectable_long_string_map_->set_is_undetectable(); obj = AllocateMap(SHORT_ASCII_STRING_TYPE, AsciiString::kHeaderSize); if (obj->IsFailure()) return false; undetectable_short_ascii_string_map_ = Map::cast(obj); undetectable_short_ascii_string_map_->set_is_undetectable(); obj = AllocateMap(MEDIUM_ASCII_STRING_TYPE, AsciiString::kHeaderSize); if (obj->IsFailure()) return false; undetectable_medium_ascii_string_map_ = Map::cast(obj); undetectable_medium_ascii_string_map_->set_is_undetectable(); obj = AllocateMap(LONG_ASCII_STRING_TYPE, AsciiString::kHeaderSize); if (obj->IsFailure()) return false; undetectable_long_ascii_string_map_ = Map::cast(obj); undetectable_long_ascii_string_map_->set_is_undetectable(); obj = AllocateMap(BYTE_ARRAY_TYPE, Array::kHeaderSize); if (obj->IsFailure()) return false; byte_array_map_ = Map::cast(obj); obj = AllocateMap(CODE_TYPE, Code::kHeaderSize); if (obj->IsFailure()) return false; code_map_ = Map::cast(obj); obj = AllocateMap(FILLER_TYPE, kPointerSize); if (obj->IsFailure()) return false; one_word_filler_map_ = Map::cast(obj); obj = AllocateMap(FILLER_TYPE, 2 * kPointerSize); if (obj->IsFailure()) return false; two_word_filler_map_ = Map::cast(obj);#define ALLOCATE_STRUCT_MAP(NAME, Name, name) \ obj = AllocateMap(NAME##_TYPE, Name::kSize); \ if (obj->IsFailure()) return false; \ name##_map_ = Map::cast(obj); STRUCT_LIST(ALLOCATE_STRUCT_MAP)#undef ALLOCATE_STRUCT_MAP obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize); if (obj->IsFailure()) return false; hash_table_map_ = Map::cast(obj); obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize); if (obj->IsFailure()) return false; context_map_ = Map::cast(obj); obj = AllocateMap(FIXED_ARRAY_TYPE, HeapObject::kHeaderSize); if (obj->IsFailure()) return false; global_context_map_ = Map::cast(obj); obj = AllocateMap(JS_FUNCTION_TYPE, JSFunction::kSize); if (obj->IsFailure()) return false; boilerplate_function_map_ = Map::cast(obj); obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kSize); if (obj->IsFailure()) return false; shared_function_info_map_ = Map::cast(obj); ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); return true;}Object* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { // Statically ensure that it is safe to allocate heap numbers in paged // spaces. STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; Object* result = AllocateRaw(HeapNumber::kSize, space); if (result->IsFailure()) return result; HeapObject::cast(result)->set_map(heap_number_map()); HeapNumber::cast(result)->set_value(value); return result;}Object* Heap::AllocateHeapNumber(double value) { // This version of AllocateHeapNumber is optimized for // allocation in new space. STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); Object* result = new_space_->AllocateRaw(HeapNumber::kSize); if (result->IsFailure()) return result; HeapObject::cast(result)->set_map(heap_number_map()); HeapNumber::cast(result)->set_value(value); return result;}Object* Heap::CreateOddball(Map* map, const char* to_string, Object* to_number) { Object* result = Allocate(map, OLD_DATA_SPACE); if (result->IsFailure()) return result; return Oddball::cast(result)->Initialize(to_string, to_number);}bool Heap::CreateApiObjects() { Object* obj; obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); if (obj->IsFailure()) return false; neander_map_ = Map::cast(obj); obj = Heap::AllocateJSObjectFromMap(neander_map_); if (obj->IsFailure()) return false; Object* elements = AllocateFixedArray(2); if (elements->IsFailure()) return false; FixedArray::cast(elements)->set(0, Smi::FromInt(0)); JSObject::cast(obj)->set_elements(FixedArray::cast(elements)); message_listeners_ = JSObject::cast(obj); obj = Heap::AllocateJSObjectFromMap(neander_map_); if (obj->IsFailure()) return false; elements = AllocateFixedArray(2); if (elements->IsFailure()) return false; FixedArray::cast(elements)->set(0, Smi::FromInt(0)); JSObject::cast(obj)->set_elements(FixedArray::cast(elements)); debug_event_listeners_ = JSObject::cast(obj); return true;}void Heap::CreateFixedStubs() { // Here we create roots for fixed stubs. They are needed at GC // for cooking and uncooking (check out frames.cc). // The eliminates the need for doing dictionary lookup in the // stub cache for these stubs. HandleScope scope; { CEntryStub stub; c_entry_code_ = *stub.GetCode(); } { CEntryDebugBreakStub stub; c_entry_debug_break_code_ = *stub.GetCode(); } { JSEntryStub stub; js_entry_code_ = *stub.GetCode(); } { JSConstructEntryStub stub; js_construct_entry_code_ = *stub.GetCode(); }}bool Heap::CreateInitialObjects() { Object* obj; // The -0 value must be set before NumberFromDouble works. obj = AllocateHeapNumber(-0.0, TENURED); if (obj->IsFailure()) return false; minus_zero_value_ = obj; ASSERT(signbit(minus_zero_value_->Number()) != 0); obj = AllocateHeapNumber(OS::nan_value(), TENURED); if (obj->IsFailure()) return false; nan_value_ = obj; obj = Allocate(oddball_map(), OLD_DATA_SPACE); if (obj->IsFailure()) return false; undefined_value_ = obj; ASSERT(!InNewSpace(undefined_value())); // Allocate initial symbol table. obj = SymbolTable::Allocate(kInitialSymbolTableSize); if (obj->IsFailure()) return false; symbol_table_ = obj; // Assign the print strings for oddballs after creating symboltable. Object* symbol = LookupAsciiSymbol("undefined"); if (symbol->IsFailure()) return false; Oddball::cast(undefined_value_)->set_to_string(String::cast(symbol)); Oddball::cast(undefined_value_)->set_to_number(nan_value_); // Assign the print strings for oddballs after creating symboltable. symbol = LookupAsciiSymbol("null"); if (symbol->IsFailure()) return false; Oddball::cast(null_value_)->set_to_string(String::cast(symbol)); Oddball::cast(null_value_)->set_to_number(Smi::FromInt(0)); // Allocate the null_value obj = Oddball::cast(null_value())->Initialize("null", Smi::FromInt(0)); if (obj->IsFailure()) return false; obj = CreateOddball(oddball_map(), "true", Smi::FromInt(1)); if (obj->IsFailure()) return false; true_value_ = obj; obj = CreateOddball(oddball_map(), "false", Smi::FromInt(0)); if (obj->IsFailure()) return false; false_value_ = obj; obj = CreateOddball(oddball_map(), "hole", Smi::FromInt(-1)); if (obj->IsFailure()) return false; the_hole_value_ = obj; // Allocate the empty string. obj = AllocateRawAsciiString(0, TENURED); if (obj->IsFailure()) return false; empty_string_ = String::cast(obj);#define SYMBOL_INITIALIZE(name, string) \ obj = LookupAsciiSymbol(string); \ if (obj->IsFailure()) return false; \ (name##_) = String::cast(obj); SYMBOL_LIST(SYMBOL_INITIALIZE)#undef SYMBOL_INITIALIZE // Allocate the proxy for __proto__. obj = AllocateProxy((Address) &Accessors::ObjectPrototype); if (obj->IsFailure()) return false; prototype_accessors_ = Proxy::cast(obj); // Allocate the code_stubs dictionary. obj = Dictionary::Allocate(4); if (obj->IsFailure()) return false; code_stubs_ = Dictionary::cast(obj); // Allocate the non_monomorphic_cache used in stub-cache.cc obj = Dictionary::Allocate(4); if (obj->IsFailure()) return false; non_monomorphic_cache_ = Dictionary::cast(obj); CreateFixedStubs(); // Allocate the number->string conversion cache obj = AllocateFixedArray(kNumberStringCacheSize * 2); if (obj->IsFailure()) return false; number_string_cache_ = FixedArray::cast(obj); // Allocate cache for single character strings. obj = AllocateFixedArray(String::kMaxAsciiCharCode+1); if (obj->IsFailure()) return false; single_character_string_cache_ = FixedArray::cast(obj); // Allocate cache for external strings pointing to native source code. obj = AllocateFixedArray(Natives::GetBuiltinsCount()); if (obj->IsFailure()) return false; natives_source_cache_ = FixedArray::cast(obj); // Initialize compilation cache. CompilationCache::Clear(); return true;}static inline int double_get_hash(double d) { DoubleRepresentation rep(d); return ((static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32)) & (Heap::kNumberStringCacheSize - 1));}static inline int smi_get_hash(Smi* smi) { return (smi->value() & (Heap::kNumberStringCacheSize - 1));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -