📄 heap.cc.svn-base
字号:
Object* Heap::GetNumberStringCache(Object* number) { int hash; if (number->IsSmi()) { hash = smi_get_hash(Smi::cast(number)); } else { hash = double_get_hash(number->Number()); } Object* key = number_string_cache_->get(hash * 2); if (key == number) { return String::cast(number_string_cache_->get(hash * 2 + 1)); } else if (key->IsHeapNumber() && number->IsHeapNumber() && key->Number() == number->Number()) { return String::cast(number_string_cache_->get(hash * 2 + 1)); } return undefined_value();}void Heap::SetNumberStringCache(Object* number, String* string) { int hash; if (number->IsSmi()) { hash = smi_get_hash(Smi::cast(number)); number_string_cache_->set(hash * 2, number, FixedArray::SKIP_WRITE_BARRIER); } else { hash = double_get_hash(number->Number()); number_string_cache_->set(hash * 2, number); } number_string_cache_->set(hash * 2 + 1, string);}Object* Heap::SmiOrNumberFromDouble(double value, bool new_object, PretenureFlag pretenure) { // We need to distinguish the minus zero value and this cannot be // done after conversion to int. Doing this by comparing bit // patterns is faster than using fpclassify() et al. static const DoubleRepresentation plus_zero(0.0); static const DoubleRepresentation minus_zero(-0.0); static const DoubleRepresentation nan(OS::nan_value()); ASSERT(minus_zero_value_ != NULL); ASSERT(sizeof(plus_zero.value) == sizeof(plus_zero.bits)); DoubleRepresentation rep(value); if (rep.bits == plus_zero.bits) return Smi::FromInt(0); // not uncommon if (rep.bits == minus_zero.bits) { return new_object ? AllocateHeapNumber(-0.0, pretenure) : minus_zero_value_; } if (rep.bits == nan.bits) { return new_object ? AllocateHeapNumber(OS::nan_value(), pretenure) : nan_value_; } // Try to represent the value as a tagged small integer. int int_value = FastD2I(value); if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { return Smi::FromInt(int_value); } // Materialize the value in the heap. return AllocateHeapNumber(value, pretenure);}Object* Heap::NewNumberFromDouble(double value, PretenureFlag pretenure) { return SmiOrNumberFromDouble(value, true /* number object must be new */, pretenure);}Object* Heap::NumberFromDouble(double value, PretenureFlag pretenure) { return SmiOrNumberFromDouble(value, false /* use preallocated NaN, -0.0 */, pretenure);}Object* Heap::AllocateProxy(Address proxy, PretenureFlag pretenure) { // Statically ensure that it is safe to allocate proxies in paged spaces. STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize); AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; Object* result = Allocate(proxy_map(), space); if (result->IsFailure()) return result; Proxy::cast(result)->set_proxy(proxy); return result;}Object* Heap::AllocateSharedFunctionInfo(Object* name) { Object* result = Allocate(shared_function_info_map(), NEW_SPACE); if (result->IsFailure()) return result; SharedFunctionInfo* share = SharedFunctionInfo::cast(result); share->set_name(name); Code* illegal = Builtins::builtin(Builtins::Illegal); share->set_code(illegal); share->set_expected_nof_properties(0); share->set_length(0); share->set_formal_parameter_count(0); share->set_instance_class_name(Object_symbol()); share->set_function_data(undefined_value()); share->set_lazy_load_data(undefined_value()); share->set_script(undefined_value()); share->set_start_position_and_type(0); share->set_debug_info(undefined_value()); return result;}Object* Heap::AllocateConsString(String* first, String* second) { int length = first->length() + second->length(); bool is_ascii = first->is_ascii() && second->is_ascii(); // If the resulting string is small make a flat string. if (length < ConsString::kMinLength) { Object* result = is_ascii ? AllocateRawAsciiString(length) : AllocateRawTwoByteString(length); if (result->IsFailure()) return result; // Copy the characters into the new object. String* string_result = String::cast(result); int first_length = first->length(); // Copy the content of the first string. for (int i = 0; i < first_length; i++) { string_result->Set(i, first->Get(i)); } int second_length = second->length(); // Copy the content of the first string. for (int i = 0; i < second_length; i++) { string_result->Set(first_length + i, second->Get(i)); } return result; } Map* map; if (length <= String::kMaxShortStringSize) { map = is_ascii ? short_cons_ascii_string_map() : short_cons_string_map(); } else if (length <= String::kMaxMediumStringSize) { map = is_ascii ? medium_cons_ascii_string_map() : medium_cons_string_map(); } else { map = is_ascii ? long_cons_ascii_string_map() : long_cons_string_map(); } Object* result = Allocate(map, NEW_SPACE); if (result->IsFailure()) return result; ConsString* cons_string = ConsString::cast(result); cons_string->set_first(first); cons_string->set_second(second); cons_string->set_length(length); return result;}Object* Heap::AllocateSlicedString(String* buffer, int start, int end) { int length = end - start; // If the resulting string is small make a sub string. if (end - start <= SlicedString::kMinLength) { return Heap::AllocateSubString(buffer, start, end); } Map* map; if (length <= String::kMaxShortStringSize) { map = buffer->is_ascii() ? short_sliced_ascii_string_map() : short_sliced_string_map(); } else if (length <= String::kMaxMediumStringSize) { map = buffer->is_ascii() ? medium_sliced_ascii_string_map() : medium_sliced_string_map(); } else { map = buffer->is_ascii() ? long_sliced_ascii_string_map() : long_sliced_string_map(); } Object* result = Allocate(map, NEW_SPACE); if (result->IsFailure()) return result; SlicedString* sliced_string = SlicedString::cast(result); sliced_string->set_buffer(buffer); sliced_string->set_start(start); sliced_string->set_length(length); return result;}Object* Heap::AllocateSubString(String* buffer, int start, int end) { int length = end - start; // Make an attempt to flatten the buffer to reduce access time. buffer->TryFlatten(); Object* result = buffer->is_ascii() ? AllocateRawAsciiString(length) : AllocateRawTwoByteString(length); if (result->IsFailure()) return result; // Copy the characters into the new object. String* string_result = String::cast(result); for (int i = 0; i < length; i++) { string_result->Set(i, buffer->Get(start + i)); } return result;}Object* Heap::AllocateExternalStringFromAscii( ExternalAsciiString::Resource* resource) { Map* map; int length = resource->length(); if (length <= String::kMaxShortStringSize) { map = short_external_ascii_string_map(); } else if (length <= String::kMaxMediumStringSize) { map = medium_external_ascii_string_map(); } else { map = long_external_ascii_string_map(); } Object* result = Allocate(map, NEW_SPACE); if (result->IsFailure()) return result; ExternalAsciiString* external_string = ExternalAsciiString::cast(result); external_string->set_length(length); external_string->set_resource(resource); return result;}Object* Heap::AllocateExternalStringFromTwoByte( ExternalTwoByteString::Resource* resource) { Map* map; int length = resource->length(); if (length <= String::kMaxShortStringSize) { map = short_external_string_map(); } else if (length <= String::kMaxMediumStringSize) { map = medium_external_string_map(); } else { map = long_external_string_map(); } Object* result = Allocate(map, NEW_SPACE); if (result->IsFailure()) return result; ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); external_string->set_length(length); external_string->set_resource(resource); return result;}Object* Heap:: LookupSingleCharacterStringFromCode(uint16_t code) { if (code <= String::kMaxAsciiCharCode) { Object* value = Heap::single_character_string_cache()->get(code); if (value != Heap::undefined_value()) return value; Object* result = Heap::AllocateRawAsciiString(1); if (result->IsFailure()) return result; String::cast(result)->Set(0, code); Heap::single_character_string_cache()->set(code, result); return result; } Object* result = Heap::AllocateRawTwoByteString(1); if (result->IsFailure()) return result; String::cast(result)->Set(0, code); return result;}Object* Heap::AllocateByteArray(int length) { int size = ByteArray::SizeFor(length); AllocationSpace space = size > MaxHeapObjectSize() ? LO_SPACE : NEW_SPACE; Object* result = AllocateRaw(size, space); if (result->IsFailure()) return result; reinterpret_cast<Array*>(result)->set_map(byte_array_map()); reinterpret_cast<Array*>(result)->set_length(length); return result;}Object* Heap::CreateCode(const CodeDesc& desc, ScopeInfo<>* sinfo, Code::Flags flags) { // Compute size int body_size = RoundUp(desc.instr_size + desc.reloc_size, kObjectAlignment); int sinfo_size = 0; if (sinfo != NULL) sinfo_size = sinfo->Serialize(NULL); int obj_size = Code::SizeFor(body_size, sinfo_size); Object* result; if (obj_size > MaxHeapObjectSize()) { result = lo_space_->AllocateRawCode(obj_size); } else { result = code_space_->AllocateRaw(obj_size); } if (result->IsFailure()) return result; // Initialize the object HeapObject::cast(result)->set_map(code_map()); Code* code = Code::cast(result); code->set_instruction_size(desc.instr_size); code->set_relocation_size(desc.reloc_size); code->set_sinfo_size(sinfo_size); code->set_flags(flags); code->set_ic_flag(Code::IC_TARGET_IS_ADDRESS); code->CopyFrom(desc); // migrate generated code if (sinfo != NULL) sinfo->Serialize(code); // write scope info#ifdef DEBUG code->Verify();#endif return code;}Object* Heap::CopyCode(Code* code) { // Allocate an object the same size as the code object. int obj_size = code->Size(); Object* result; if (obj_size > MaxHeapObjectSize()) { result = lo_space_->AllocateRawCode(obj_size); } else { result = code_space_->AllocateRaw(obj_size); } if (result->IsFailure()) return result; // Copy code object. Address old_addr = code->address(); Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); memcpy(new_addr, old_addr, obj_size); // Relocate the copy. Code* new_code = Code::cast(result); new_code->Relocate(new_addr - old_addr); return new_code;}Object* Heap::Allocate(Map* map, AllocationSpace space) { ASSERT(gc_state_ == NOT_IN_GC); ASSERT(map->instance_type() != MAP_TYPE); Object* result = AllocateRaw(map->instance_size(), space); if (result->IsFailure()) return result; HeapObject::cast(result)->set_map(map); return result;}Object* Heap::InitializeFunction(JSFunction* function, SharedFunctionInfo* shared, Object* prototype) { ASSERT(!prototype->IsMap()); function->initialize_properties(); function->initialize_elements(); function->set_shared(shared); function->set_prototype_or_initial_map(prototype); function->set_context(undefined_value()); function->set_literals(empty_fixed_array()); return function;}Object* Heap::AllocateFunctionPrototype(JSFunction* function) { // Allocate the prototype. Object* prototype = AllocateJSObject(Top::context()->global_context()->object_function()); if (prototype->IsFailure()) return prototype; // When creating the prototype for the function we must set its // constructor to the function. Object* result = JSObject::cast(prototype)->SetProperty(constructor_symbol(), function, DONT_ENUM); if (result->IsFailure()) return result; return prototype;}Object* Heap::AllocateFunction(Map* function_map, SharedFunctionInfo* shared, Object* prototype) { Object* result = Allocate(function_map, OLD_POINTER_SPACE); if (result->IsFailure()) return result; return InitializeFunction(JSFunction::cast(result), shared, prototype);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -