HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Pie
|
9.0.0_r8
下载
查看原文件
收藏
根目录
external
v8
src
factory.cc
// Copyright 2014 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/factory.h" #include "src/accessors.h" #include "src/allocation-site-scopes.h" #include "src/ast/ast.h" #include "src/base/bits.h" #include "src/bootstrapper.h" #include "src/compiler.h" #include "src/conversions.h" #include "src/isolate-inl.h" #include "src/macro-assembler.h" #include "src/objects/module-info.h" #include "src/objects/scope-info.h" namespace v8 { namespace internal { // Calls the FUNCTION_CALL function and retries it up to three times // to guarantee that any allocations performed during the call will // succeed if there's enough memory. // // Warning: Do not use the identifiers __object__, __maybe_object__, // __allocation__ or __scope__ in a call to this macro. #define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ if (__allocation__.To(&__object__)) { \ DCHECK(__object__ != (ISOLATE)->heap()->exception()); \ return Handle
(TYPE::cast(__object__), ISOLATE); \ } #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ do { \ AllocationResult __allocation__ = FUNCTION_CALL; \ Object* __object__ = NULL; \ RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ /* Two GCs before panicking. In newspace will almost always succeed. */ \ for (int __i__ = 0; __i__ < 2; __i__++) { \ (ISOLATE)->heap()->CollectGarbage( \ __allocation__.RetrySpace(), \ GarbageCollectionReason::kAllocationFailure); \ __allocation__ = FUNCTION_CALL; \ RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ } \ (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \ (ISOLATE)->heap()->CollectAllAvailableGarbage( \ GarbageCollectionReason::kLastResort); \ { \ AlwaysAllocateScope __scope__(ISOLATE); \ __allocation__ = FUNCTION_CALL; \ } \ RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ /* TODO(1181417): Fix this. */ \ v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \ return Handle
(); \ } while (false) template
Handle
Factory::New(Handle
map, AllocationSpace space) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->Allocate(*map, space), T); } template
Handle
Factory::New(Handle
map, AllocationSpace space, Handle
allocation_site) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->Allocate(*map, space, *allocation_site), T); } Handle
Factory::NewFillerObject(int size, bool double_align, AllocationSpace space) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateFillerObject(size, double_align, space), HeapObject); } Handle
Factory::NewPrototypeInfo() { Handle
result = Handle
::cast(NewStruct(PROTOTYPE_INFO_TYPE)); result->set_prototype_users(WeakFixedArray::Empty()); result->set_registry_slot(PrototypeInfo::UNREGISTERED); result->set_validity_cell(Smi::kZero); result->set_bit_field(0); return result; } Handle
Factory::NewTuple2(Handle
value1, Handle
value2) { Handle
result = Handle
::cast(NewStruct(TUPLE2_TYPE)); result->set_value1(*value1); result->set_value2(*value2); return result; } Handle
Factory::NewTuple3(Handle
value1, Handle
value2, Handle
value3) { Handle
result = Handle
::cast(NewStruct(TUPLE3_TYPE)); result->set_value1(*value1); result->set_value2(*value2); result->set_value3(*value3); return result; } Handle
Factory::NewContextExtension( Handle
scope_info, Handle
extension) { Handle
result = Handle
::cast(NewStruct(CONTEXT_EXTENSION_TYPE)); result->set_scope_info(*scope_info); result->set_extension(*extension); return result; } Handle
Factory::NewConstantElementsPair( ElementsKind elements_kind, Handle
constant_values) { Handle
result = Handle
::cast( NewStruct(CONSTANT_ELEMENTS_PAIR_TYPE)); result->set_elements_kind(elements_kind); result->set_constant_values(*constant_values); return result; } Handle
Factory::NewOddball(Handle
map, const char* to_string, Handle
to_number, const char* type_of, byte kind) { Handle
oddball = New
(map, OLD_SPACE); Oddball::Initialize(isolate(), oddball, to_string, to_number, type_of, kind); return oddball; } Handle
Factory::NewFixedArray(int size, PretenureFlag pretenure) { DCHECK(0 <= size); CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateFixedArray(size, pretenure), FixedArray); } MaybeHandle
Factory::TryNewFixedArray(int size, PretenureFlag pretenure) { DCHECK(0 <= size); AllocationResult allocation = isolate()->heap()->AllocateFixedArray(size, pretenure); Object* array = NULL; if (!allocation.To(&array)) return MaybeHandle
(); return Handle
(FixedArray::cast(array), isolate()); } Handle
Factory::NewFixedArrayWithHoles(int size, PretenureFlag pretenure) { DCHECK(0 <= size); CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateFixedArrayWithFiller(size, pretenure, *the_hole_value()), FixedArray); } Handle
Factory::NewUninitializedFixedArray(int size) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateUninitializedFixedArray(size), FixedArray); } Handle
Factory::NewBoilerplateDescription( int boilerplate, int all_properties, int index_keys, bool has_seen_proto) { DCHECK_GE(boilerplate, 0); DCHECK_GE(all_properties, index_keys); DCHECK_GE(index_keys, 0); int backing_store_size = all_properties - index_keys - (has_seen_proto ? 1 : 0); DCHECK_GE(backing_store_size, 0); bool has_different_size_backing_store = boilerplate != backing_store_size; // Space for name and value for every boilerplate property. int size = 2 * boilerplate; if (has_different_size_backing_store) { // An extra entry for the backing store size. size++; } Handle
description = Handle
::cast(NewFixedArray(size, TENURED)); if (has_different_size_backing_store) { DCHECK((boilerplate != (all_properties - index_keys)) || has_seen_proto); description->set_backing_store_size(isolate(), backing_store_size); } return description; } Handle
Factory::NewFixedDoubleArray(int size, PretenureFlag pretenure) { DCHECK(0 <= size); CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure), FixedArrayBase); } Handle
Factory::NewFixedDoubleArrayWithHoles( int size, PretenureFlag pretenure) { DCHECK(0 <= size); Handle
array = NewFixedDoubleArray(size, pretenure); if (size > 0) { Handle
::cast(array)->FillWithHoles(0, size); } return array; } Handle
Factory::NewFrameArray(int number_of_frames, PretenureFlag pretenure) { DCHECK_LE(0, number_of_frames); Handle
result = NewFixedArrayWithHoles(FrameArray::LengthFor(number_of_frames)); result->set(FrameArray::kFrameCountIndex, Smi::kZero); return Handle
::cast(result); } Handle
Factory::NewOrderedHashSet() { return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity); } Handle
Factory::NewOrderedHashMap() { return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity); } Handle
Factory::NewAccessorPair() { Handle
accessors = Handle
::cast(NewStruct(ACCESSOR_PAIR_TYPE)); accessors->set_getter(*null_value(), SKIP_WRITE_BARRIER); accessors->set_setter(*null_value(), SKIP_WRITE_BARRIER); return accessors; } Handle
Factory::NewTypeFeedbackInfo() { Handle
info = Handle
::cast(NewStruct(TYPE_FEEDBACK_INFO_TYPE)); info->initialize_storage(); return info; } // Internalized strings are created in the old generation (data space). Handle
Factory::InternalizeUtf8String(Vector
string) { Utf8StringKey key(string, isolate()->heap()->HashSeed()); return InternalizeStringWithKey(&key); } Handle
Factory::InternalizeOneByteString(Vector
string) { OneByteStringKey key(string, isolate()->heap()->HashSeed()); return InternalizeStringWithKey(&key); } Handle
Factory::InternalizeOneByteString( Handle
string, int from, int length) { SeqOneByteSubStringKey key(string, from, length); return InternalizeStringWithKey(&key); } Handle
Factory::InternalizeTwoByteString(Vector
string) { TwoByteStringKey key(string, isolate()->heap()->HashSeed()); return InternalizeStringWithKey(&key); } template
Handle
Factory::InternalizeStringWithKey(StringTableKey* key) { return StringTable::LookupKey(isolate(), key); } MaybeHandle
Factory::NewStringFromOneByte(Vector
string, PretenureFlag pretenure) { int length = string.length(); if (length == 0) return empty_string(); if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); Handle
result; ASSIGN_RETURN_ON_EXCEPTION( isolate(), result, NewRawOneByteString(string.length(), pretenure), String); DisallowHeapAllocation no_gc; // Copy the characters into the new object. CopyChars(SeqOneByteString::cast(*result)->GetChars(), string.start(), length); return result; } MaybeHandle
Factory::NewStringFromUtf8(Vector
string, PretenureFlag pretenure) { // Check for ASCII first since this is the common case. const char* start = string.start(); int length = string.length(); int non_ascii_start = String::NonAsciiStart(start, length); if (non_ascii_start >= length) { // If the string is ASCII, we do not need to convert the characters // since UTF8 is backwards compatible with ASCII. return NewStringFromOneByte(Vector
::cast(string), pretenure); } // Non-ASCII and we need to decode. Access
decoder(isolate()->unicode_cache()->utf8_decoder()); decoder->Reset(string.start() + non_ascii_start, length - non_ascii_start); int utf16_length = static_cast
(decoder->Utf16Length()); DCHECK(utf16_length > 0); // Allocate string. Handle
result; ASSIGN_RETURN_ON_EXCEPTION( isolate(), result, NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String); // Copy ASCII portion. uint16_t* data = result->GetChars(); const char* ascii_data = string.start(); for (int i = 0; i < non_ascii_start; i++) { *data++ = *ascii_data++; } // Now write the remainder. decoder->WriteUtf16(data, utf16_length); return result; } MaybeHandle
Factory::NewStringFromUtf8SubString( Handle
str, int begin, int length, PretenureFlag pretenure) { // Check for ASCII first since this is the common case. const char* start = reinterpret_cast
(str->GetChars() + begin); int non_ascii_start = String::NonAsciiStart(start, length); if (non_ascii_start >= length) { // If the string is ASCII, we can just make a substring. // TODO(v8): the pretenure flag is ignored in this case. return NewSubString(str, begin, begin + length); } // Non-ASCII and we need to decode. Access
decoder( isolate()->unicode_cache()->utf8_decoder()); decoder->Reset(start + non_ascii_start, length - non_ascii_start); int utf16_length = static_cast
(decoder->Utf16Length()); DCHECK(utf16_length > 0); // Allocate string. Handle
result; ASSIGN_RETURN_ON_EXCEPTION( isolate(), result, NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String); // Reset the decoder, because the original {str} may have moved. const char* ascii_data = reinterpret_cast
(str->GetChars() + begin); decoder->Reset(ascii_data + non_ascii_start, length - non_ascii_start); // Copy ASCII portion. uint16_t* data = result->GetChars(); for (int i = 0; i < non_ascii_start; i++) { *data++ = *ascii_data++; } // Now write the remainder. decoder->WriteUtf16(data, utf16_length); return result; } MaybeHandle
Factory::NewStringFromTwoByte(const uc16* string, int length, PretenureFlag pretenure) { if (length == 0) return empty_string(); if (String::IsOneByte(string, length)) { if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); Handle
result; ASSIGN_RETURN_ON_EXCEPTION( isolate(), result, NewRawOneByteString(length, pretenure), String); CopyChars(result->GetChars(), string, length); return result; } else { Handle
result; ASSIGN_RETURN_ON_EXCEPTION( isolate(), result, NewRawTwoByteString(length, pretenure), String); CopyChars(result->GetChars(), string, length); return result; } } MaybeHandle
Factory::NewStringFromTwoByte(Vector
string, PretenureFlag pretenure) { return NewStringFromTwoByte(string.start(), string.length(), pretenure); } MaybeHandle
Factory::NewStringFromTwoByte( const ZoneVector
* string, PretenureFlag pretenure) { return NewStringFromTwoByte(string->data(), static_cast
(string->size()), pretenure); } Handle
Factory::NewInternalizedStringFromUtf8(Vector
str, int chars, uint32_t hash_field) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateInternalizedStringFromUtf8( str, chars, hash_field), String); } MUST_USE_RESULT Handle
Factory::NewOneByteInternalizedString( Vector
str, uint32_t hash_field) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateOneByteInternalizedString(str, hash_field), String); } MUST_USE_RESULT Handle
Factory::NewOneByteInternalizedSubString( Handle
string, int offset, int length, uint32_t hash_field) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateOneByteInternalizedString( Vector
(string->GetChars() + offset, length), hash_field), String); } MUST_USE_RESULT Handle
Factory::NewTwoByteInternalizedString( Vector
str, uint32_t hash_field) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateTwoByteInternalizedString(str, hash_field), String); } Handle
Factory::NewInternalizedStringImpl( Handle
string, int chars, uint32_t hash_field) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateInternalizedStringImpl( *string, chars, hash_field), String); } namespace { MaybeHandle
GetInternalizedStringMap(Factory* f, Handle
string) { switch (string->map()->instance_type()) { case STRING_TYPE: return f->internalized_string_map(); case ONE_BYTE_STRING_TYPE: return f->one_byte_internalized_string_map(); case EXTERNAL_STRING_TYPE: return f->external_internalized_string_map(); case EXTERNAL_ONE_BYTE_STRING_TYPE: return f->external_one_byte_internalized_string_map(); case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: return f->external_internalized_string_with_one_byte_data_map(); case SHORT_EXTERNAL_STRING_TYPE: return f->short_external_internalized_string_map(); case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: return f->short_external_one_byte_internalized_string_map(); case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: return f->short_external_internalized_string_with_one_byte_data_map(); default: return MaybeHandle
(); // No match found. } } } // namespace MaybeHandle
Factory::InternalizedStringMapForString( Handle
string) { // If the string is in new space it cannot be used as internalized. if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle
(); return GetInternalizedStringMap(this, string); } template
Handle
Factory::InternalizeExternalString(Handle
string) { Handle
cast_string = Handle
::cast(string); Handle
map = GetInternalizedStringMap(this, string).ToHandleChecked(); Handle
external_string = New
(map, OLD_SPACE); external_string->set_length(cast_string->length()); external_string->set_hash_field(cast_string->hash_field()); external_string->set_resource(nullptr); isolate()->heap()->RegisterExternalString(*external_string); return external_string; } template Handle
Factory::InternalizeExternalString
(Handle
); template Handle
Factory::InternalizeExternalString
(Handle
); MaybeHandle
Factory::NewRawOneByteString( int length, PretenureFlag pretenure) { if (length > String::kMaxLength || length < 0) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); } DCHECK(length > 0); // Use Factory::empty_string() instead. CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateRawOneByteString(length, pretenure), SeqOneByteString); } MaybeHandle
Factory::NewRawTwoByteString( int length, PretenureFlag pretenure) { if (length > String::kMaxLength || length < 0) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); } DCHECK(length > 0); // Use Factory::empty_string() instead. CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateRawTwoByteString(length, pretenure), SeqTwoByteString); } Handle
Factory::LookupSingleCharacterStringFromCode(uint32_t code) { if (code <= String::kMaxOneByteCharCodeU) { { DisallowHeapAllocation no_allocation; Object* value = single_character_string_cache()->get(code); if (value != *undefined_value()) { return handle(String::cast(value), isolate()); } } uint8_t buffer[1]; buffer[0] = static_cast
(code); Handle
result = InternalizeOneByteString(Vector
(buffer, 1)); single_character_string_cache()->set(code, *result); return result; } DCHECK(code <= String::kMaxUtf16CodeUnitU); Handle
result = NewRawTwoByteString(1).ToHandleChecked(); result->SeqTwoByteStringSet(0, static_cast
(code)); return result; } // Returns true for a character in a range. Both limits are inclusive. static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { // This makes uses of the the unsigned wraparound. return character - from <= to - from; } static inline Handle
MakeOrFindTwoCharacterString(Isolate* isolate, uint16_t c1, uint16_t c2) { // Numeric strings have a different hash algorithm not known by // LookupTwoCharsStringIfExists, so we skip this step for such strings. if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) { Handle
result; if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2). ToHandle(&result)) { return result; } } // Now we know the length is 2, we might as well make use of that fact // when building the new string. if (static_cast
(c1 | c2) <= String::kMaxOneByteCharCodeU) { // We can do this. DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU + 1)); // because of this. Handle
str = isolate->factory()->NewRawOneByteString(2).ToHandleChecked(); uint8_t* dest = str->GetChars(); dest[0] = static_cast
(c1); dest[1] = static_cast
(c2); return str; } else { Handle
str = isolate->factory()->NewRawTwoByteString(2).ToHandleChecked(); uc16* dest = str->GetChars(); dest[0] = c1; dest[1] = c2; return str; } } template
Handle
ConcatStringContent(Handle
result, Handle
first, Handle
second) { DisallowHeapAllocation pointer_stays_valid; SinkChar* sink = result->GetChars(); String::WriteToFlat(*first, sink, 0, first->length()); String::WriteToFlat(*second, sink + first->length(), 0, second->length()); return result; } MaybeHandle
Factory::NewConsString(Handle
left, Handle
right) { if (left->IsThinString()) { left = handle(Handle
::cast(left)->actual(), isolate()); } if (right->IsThinString()) { right = handle(Handle
::cast(right)->actual(), isolate()); } int left_length = left->length(); if (left_length == 0) return right; int right_length = right->length(); if (right_length == 0) return left; int length = left_length + right_length; if (length == 2) { uint16_t c1 = left->Get(0); uint16_t c2 = right->Get(0); return MakeOrFindTwoCharacterString(isolate(), c1, c2); } // Make sure that an out of memory exception is thrown if the length // of the new cons string is too large. if (length > String::kMaxLength || length < 0) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } bool left_is_one_byte = left->IsOneByteRepresentation(); bool right_is_one_byte = right->IsOneByteRepresentation(); bool is_one_byte = left_is_one_byte && right_is_one_byte; bool is_one_byte_data_in_two_byte_string = false; if (!is_one_byte) { // At least one of the strings uses two-byte representation so we // can't use the fast case code for short one-byte strings below, but // we can try to save memory if all chars actually fit in one-byte. is_one_byte_data_in_two_byte_string = left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars(); if (is_one_byte_data_in_two_byte_string) { isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment(); } } // If the resulting string is small make a flat string. if (length < ConsString::kMinLength) { // Note that neither of the two inputs can be a slice because: STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); DCHECK(left->IsFlat()); DCHECK(right->IsFlat()); STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); if (is_one_byte) { Handle
result = NewRawOneByteString(length).ToHandleChecked(); DisallowHeapAllocation no_gc; uint8_t* dest = result->GetChars(); // Copy left part. const uint8_t* src = left->IsExternalString() ? Handle
::cast(left)->GetChars() : Handle
::cast(left)->GetChars(); for (int i = 0; i < left_length; i++) *dest++ = src[i]; // Copy right part. src = right->IsExternalString() ? Handle
::cast(right)->GetChars() : Handle
::cast(right)->GetChars(); for (int i = 0; i < right_length; i++) *dest++ = src[i]; return result; } return (is_one_byte_data_in_two_byte_string) ? ConcatStringContent
( NewRawOneByteString(length).ToHandleChecked(), left, right) : ConcatStringContent
( NewRawTwoByteString(length).ToHandleChecked(), left, right); } Handle
result = (is_one_byte || is_one_byte_data_in_two_byte_string) ? New
(cons_one_byte_string_map(), NEW_SPACE) : New
(cons_string_map(), NEW_SPACE); DisallowHeapAllocation no_gc; WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); result->set_hash_field(String::kEmptyHashField); result->set_length(length); result->set_first(*left, mode); result->set_second(*right, mode); return result; } Handle
Factory::NewSurrogatePairString(uint16_t lead, uint16_t trail) { DCHECK_GE(lead, 0xD800); DCHECK_LE(lead, 0xDBFF); DCHECK_GE(trail, 0xDC00); DCHECK_LE(trail, 0xDFFF); Handle
str = isolate()->factory()->NewRawTwoByteString(2).ToHandleChecked(); uc16* dest = str->GetChars(); dest[0] = lead; dest[1] = trail; return str; } Handle
Factory::NewProperSubString(Handle
str, int begin, int end) { #if VERIFY_HEAP if (FLAG_verify_heap) str->StringVerify(); #endif DCHECK(begin > 0 || end < str->length()); str = String::Flatten(str); int length = end - begin; if (length <= 0) return empty_string(); if (length == 1) { return LookupSingleCharacterStringFromCode(str->Get(begin)); } if (length == 2) { // Optimization for 2-byte strings often used as keys in a decompression // dictionary. Check whether we already have the string in the string // table to prevent creation of many unnecessary strings. uint16_t c1 = str->Get(begin); uint16_t c2 = str->Get(begin + 1); return MakeOrFindTwoCharacterString(isolate(), c1, c2); } if (!FLAG_string_slices || length < SlicedString::kMinLength) { if (str->IsOneByteRepresentation()) { Handle
result = NewRawOneByteString(length).ToHandleChecked(); uint8_t* dest = result->GetChars(); DisallowHeapAllocation no_gc; String::WriteToFlat(*str, dest, begin, end); return result; } else { Handle
result = NewRawTwoByteString(length).ToHandleChecked(); uc16* dest = result->GetChars(); DisallowHeapAllocation no_gc; String::WriteToFlat(*str, dest, begin, end); return result; } } int offset = begin; if (str->IsSlicedString()) { Handle
slice = Handle
::cast(str); str = Handle
(slice->parent(), isolate()); offset += slice->offset(); } if (str->IsThinString()) { Handle
thin = Handle
::cast(str); str = handle(thin->actual(), isolate()); } DCHECK(str->IsSeqString() || str->IsExternalString()); Handle
map = str->IsOneByteRepresentation() ? sliced_one_byte_string_map() : sliced_string_map(); Handle
slice = New
(map, NEW_SPACE); slice->set_hash_field(String::kEmptyHashField); slice->set_length(length); slice->set_parent(*str); slice->set_offset(offset); return slice; } MaybeHandle
Factory::NewExternalStringFromOneByte( const ExternalOneByteString::Resource* resource) { size_t length = resource->length(); if (length > static_cast
(String::kMaxLength)) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } if (length == 0) return empty_string(); Handle
map; if (resource->IsCompressible()) { // TODO(hajimehoshi): Rename this to 'uncached_external_one_byte_string_map' map = short_external_one_byte_string_map(); } else { map = external_one_byte_string_map(); } Handle
external_string = New
(map, NEW_SPACE); external_string->set_length(static_cast
(length)); external_string->set_hash_field(String::kEmptyHashField); external_string->set_resource(resource); return external_string; } MaybeHandle
Factory::NewExternalStringFromTwoByte( const ExternalTwoByteString::Resource* resource) { size_t length = resource->length(); if (length > static_cast
(String::kMaxLength)) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } if (length == 0) return empty_string(); // For small strings we check whether the resource contains only // one byte characters. If yes, we use a different string map. static const size_t kOneByteCheckLengthLimit = 32; bool is_one_byte = length <= kOneByteCheckLengthLimit && String::IsOneByte(resource->data(), static_cast
(length)); Handle
map; if (resource->IsCompressible()) { // TODO(hajimehoshi): Rename these to 'uncached_external_string_...'. map = is_one_byte ? short_external_string_with_one_byte_data_map() : short_external_string_map(); } else { map = is_one_byte ? external_string_with_one_byte_data_map() : external_string_map(); } Handle
external_string = New
(map, NEW_SPACE); external_string->set_length(static_cast
(length)); external_string->set_hash_field(String::kEmptyHashField); external_string->set_resource(resource); return external_string; } Handle
Factory::NewNativeSourceString( const ExternalOneByteString::Resource* resource) { size_t length = resource->length(); DCHECK_LE(length, static_cast
(String::kMaxLength)); Handle
map = native_source_string_map(); Handle
external_string = New
(map, OLD_SPACE); external_string->set_length(static_cast
(length)); external_string->set_hash_field(String::kEmptyHashField); external_string->set_resource(resource); return external_string; } Handle
Factory::NewJSStringIterator(Handle
string) { Handle
map(isolate()->native_context()->string_iterator_map(), isolate()); Handle
flat_string = String::Flatten(string); Handle
iterator = Handle
::cast(NewJSObjectFromMap(map)); iterator->set_string(*flat_string); iterator->set_index(0); return iterator; } Handle
Factory::NewSymbol() { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateSymbol(), Symbol); } Handle
Factory::NewPrivateSymbol() { Handle
symbol = NewSymbol(); symbol->set_is_private(true); return symbol; } Handle
Factory::NewNativeContext() { Handle
array = NewFixedArray(Context::NATIVE_CONTEXT_SLOTS, TENURED); array->set_map_no_write_barrier(*native_context_map()); Handle
context = Handle
::cast(array); context->set_native_context(*context); context->set_errors_thrown(Smi::kZero); context->set_math_random_index(Smi::kZero); Handle
weak_cell = NewWeakCell(context); context->set_self_weak_cell(*weak_cell); DCHECK(context->IsNativeContext()); return context; } Handle
Factory::NewScriptContext(Handle
function, Handle
scope_info) { DCHECK_EQ(scope_info->scope_type(), SCRIPT_SCOPE); Handle
array = NewFixedArray(scope_info->ContextLength(), TENURED); array->set_map_no_write_barrier(*script_context_map()); Handle
context = Handle
::cast(array); context->set_closure(*function); context->set_previous(function->context()); context->set_extension(*scope_info); context->set_native_context(function->native_context()); DCHECK(context->IsScriptContext()); return context; } Handle
Factory::NewScriptContextTable() { Handle
array = NewFixedArray(1); array->set_map_no_write_barrier(*script_context_table_map()); Handle
context_table = Handle
::cast(array); context_table->set_used(0); return context_table; } Handle
Factory::NewModuleContext(Handle
module, Handle
function, Handle
scope_info) { DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE); Handle
array = NewFixedArray(scope_info->ContextLength(), TENURED); array->set_map_no_write_barrier(*module_context_map()); Handle
context = Handle
::cast(array); context->set_closure(*function); context->set_previous(function->context()); context->set_extension(*module); context->set_native_context(function->native_context()); DCHECK(context->IsModuleContext()); return context; } Handle
Factory::NewFunctionContext(int length, Handle
function, ScopeType scope_type) { DCHECK(function->shared()->scope_info()->scope_type() == scope_type); DCHECK(length >= Context::MIN_CONTEXT_SLOTS); Handle
array = NewFixedArray(length); Handle
map; switch (scope_type) { case EVAL_SCOPE: map = eval_context_map(); break; case FUNCTION_SCOPE: map = function_context_map(); break; default: UNREACHABLE(); } array->set_map_no_write_barrier(*map); Handle
context = Handle
::cast(array); context->set_closure(*function); context->set_previous(function->context()); context->set_extension(*the_hole_value()); context->set_native_context(function->native_context()); return context; } Handle
Factory::NewCatchContext(Handle
function, Handle
previous, Handle
scope_info, Handle
name, Handle
thrown_object) { STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX); Handle
extension = NewContextExtension(scope_info, name); Handle
array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1); array->set_map_no_write_barrier(*catch_context_map()); Handle
context = Handle
::cast(array); context->set_closure(*function); context->set_previous(*previous); context->set_extension(*extension); context->set_native_context(previous->native_context()); context->set(Context::THROWN_OBJECT_INDEX, *thrown_object); return context; } Handle
Factory::NewDebugEvaluateContext(Handle
previous, Handle
scope_info, Handle
extension, Handle
wrapped, Handle
whitelist) { STATIC_ASSERT(Context::WHITE_LIST_INDEX == Context::MIN_CONTEXT_SLOTS + 1); DCHECK(scope_info->IsDebugEvaluateScope()); Handle
context_extension = NewContextExtension( scope_info, extension.is_null() ? Handle
::cast(undefined_value()) : Handle
::cast(extension)); Handle
array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 2); array->set_map_no_write_barrier(*debug_evaluate_context_map()); Handle
c = Handle