summaryrefslogtreecommitdiff
path: root/deps/v8/src/factory.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/factory.cc')
-rw-r--r--deps/v8/src/factory.cc213
1 files changed, 134 insertions, 79 deletions
diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc
index fab539bf8b..6fd8e8c61e 100644
--- a/deps/v8/src/factory.cc
+++ b/deps/v8/src/factory.cc
@@ -17,7 +17,9 @@
#include "src/objects/bigint.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/frame-array-inl.h"
+#include "src/objects/microtask-inl.h"
#include "src/objects/module.h"
+#include "src/objects/promise-inl.h"
#include "src/objects/scope-info.h"
#include "src/unicode-cache.h"
#include "src/unicode-decoder.h"
@@ -149,13 +151,11 @@ Handle<ConstantElementsPair> Factory::NewConstantElementsPair(
}
Handle<TemplateObjectDescription> Factory::NewTemplateObjectDescription(
- int hash, Handle<FixedArray> raw_strings,
- Handle<FixedArray> cooked_strings) {
+ Handle<FixedArray> raw_strings, Handle<FixedArray> cooked_strings) {
DCHECK_EQ(raw_strings->length(), cooked_strings->length());
DCHECK_LT(0, raw_strings->length());
Handle<TemplateObjectDescription> result =
- Handle<TemplateObjectDescription>::cast(NewStruct(TUPLE3_TYPE, TENURED));
- result->set_hash(hash);
+ Handle<TemplateObjectDescription>::cast(NewStruct(TUPLE2_TYPE, TENURED));
result->set_raw_strings(*raw_strings);
result->set_cooked_strings(*cooked_strings);
return result;
@@ -222,7 +222,8 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int length,
FixedArray);
}
-Handle<FixedArray> Factory::NewUninitializedFixedArray(int length) {
+Handle<FixedArray> Factory::NewUninitializedFixedArray(
+ int length, PretenureFlag pretenure) {
DCHECK_LE(0, length);
if (length == 0) return empty_fixed_array();
@@ -230,7 +231,7 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(int length) {
// array. After getting canary/performance coverage, either remove the
// function or revert to returning uninitilized array.
CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateFixedArray(length, NOT_TENURED),
+ isolate()->heap()->AllocateFixedArray(length, pretenure),
FixedArray);
}
@@ -391,9 +392,9 @@ MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
PretenureFlag pretenure) {
// Check for ASCII first since this is the common case.
- const char* start = string.start();
+ const char* ascii_data = string.start();
int length = string.length();
- int non_ascii_start = String::NonAsciiStart(start, length);
+ int non_ascii_start = String::NonAsciiStart(ascii_data, 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.
@@ -401,35 +402,38 @@ MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
}
// Non-ASCII and we need to decode.
+ auto non_ascii = string.SubVector(non_ascii_start, length);
Access<UnicodeCache::Utf8Decoder>
decoder(isolate()->unicode_cache()->utf8_decoder());
- decoder->Reset(string.start() + non_ascii_start,
- length - non_ascii_start);
+ decoder->Reset(non_ascii);
+
int utf16_length = static_cast<int>(decoder->Utf16Length());
DCHECK_GT(utf16_length, 0);
+
// Allocate string.
Handle<SeqTwoByteString> 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);
+ decoder->WriteUtf16(data, utf16_length, non_ascii);
return result;
}
MaybeHandle<String> Factory::NewStringFromUtf8SubString(
Handle<SeqOneByteString> str, int begin, int length,
PretenureFlag pretenure) {
- // Check for ASCII first since this is the common case.
- const char* start = reinterpret_cast<const char*>(str->GetChars() + begin);
- int non_ascii_start = String::NonAsciiStart(start, length);
+ const char* ascii_data =
+ reinterpret_cast<const char*>(str->GetChars() + begin);
+ int non_ascii_start = String::NonAsciiStart(ascii_data, 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.
@@ -437,28 +441,35 @@ MaybeHandle<String> Factory::NewStringFromUtf8SubString(
}
// Non-ASCII and we need to decode.
+ auto non_ascii = Vector<const char>(ascii_data + non_ascii_start,
+ length - non_ascii_start);
Access<UnicodeCache::Utf8Decoder> decoder(
isolate()->unicode_cache()->utf8_decoder());
- decoder->Reset(start + non_ascii_start, length - non_ascii_start);
+ decoder->Reset(non_ascii);
+
int utf16_length = static_cast<int>(decoder->Utf16Length());
DCHECK_GT(utf16_length, 0);
+
// Allocate string.
Handle<SeqTwoByteString> 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<const char*>(str->GetChars() + begin);
- decoder->Reset(ascii_data + non_ascii_start, length - non_ascii_start);
+ // Update pointer references, since the original string may have moved after
+ // allocation.
+ ascii_data = reinterpret_cast<const char*>(str->GetChars() + begin);
+ non_ascii = Vector<const char>(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);
+ decoder->WriteUtf16(data, utf16_length, non_ascii);
return result;
}
@@ -985,6 +996,12 @@ Handle<Symbol> Factory::NewPrivateSymbol() {
return symbol;
}
+Handle<Symbol> Factory::NewPrivateFieldSymbol() {
+ Handle<Symbol> symbol = NewSymbol();
+ symbol->set_is_private_field();
+ return symbol;
+}
+
Handle<Context> Factory::NewNativeContext() {
Handle<FixedArray> array =
NewFixedArray(Context::NATIVE_CONTEXT_SLOTS, TENURED);
@@ -1186,6 +1203,38 @@ Handle<Script> Factory::NewScript(Handle<String> source) {
return script;
}
+Handle<CallableTask> Factory::NewCallableTask(Handle<JSReceiver> callable,
+ Handle<Context> context) {
+ DCHECK(callable->IsCallable());
+ Handle<CallableTask> microtask =
+ Handle<CallableTask>::cast(NewStruct(CALLABLE_TASK_TYPE));
+ microtask->set_callable(*callable);
+ microtask->set_context(*context);
+ return microtask;
+}
+
+Handle<CallbackTask> Factory::NewCallbackTask(Handle<Foreign> callback,
+ Handle<Foreign> data) {
+ Handle<CallbackTask> microtask =
+ Handle<CallbackTask>::cast(NewStruct(CALLBACK_TASK_TYPE));
+ microtask->set_callback(*callback);
+ microtask->set_data(*data);
+ return microtask;
+}
+
+Handle<PromiseResolveThenableJobTask> Factory::NewPromiseResolveThenableJobTask(
+ Handle<JSPromise> promise_to_resolve, Handle<JSReceiver> then,
+ Handle<JSReceiver> thenable, Handle<Context> context) {
+ DCHECK(then->IsCallable());
+ Handle<PromiseResolveThenableJobTask> microtask =
+ Handle<PromiseResolveThenableJobTask>::cast(
+ NewStruct(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE));
+ microtask->set_promise_to_resolve(*promise_to_resolve);
+ microtask->set_then(*then);
+ microtask->set_thenable(*thenable);
+ microtask->set_context(*context);
+ return microtask;
+}
Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(isolate(),
@@ -1194,11 +1243,6 @@ Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) {
}
-Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) {
- return NewForeign((Address) desc, TENURED);
-}
-
-
Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) {
DCHECK_LE(0, length);
CALL_HEAP_FUNCTION(
@@ -1247,22 +1291,28 @@ Handle<Cell> Factory::NewCell(Handle<Object> value) {
Cell);
}
-Handle<Cell> Factory::NewNoClosuresCell(Handle<Object> value) {
- Handle<Cell> cell = NewCell(value);
- cell->set_map_no_write_barrier(*no_closures_cell_map());
- return cell;
+Handle<FeedbackCell> Factory::NewNoClosuresCell(Handle<HeapObject> value) {
+ AllowDeferredHandleDereference convert_to_cell;
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateFeedbackCell(
+ isolate()->heap()->no_closures_cell_map(), *value),
+ FeedbackCell);
}
-Handle<Cell> Factory::NewOneClosureCell(Handle<Object> value) {
- Handle<Cell> cell = NewCell(value);
- cell->set_map_no_write_barrier(*one_closure_cell_map());
- return cell;
+Handle<FeedbackCell> Factory::NewOneClosureCell(Handle<HeapObject> value) {
+ AllowDeferredHandleDereference convert_to_cell;
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateFeedbackCell(
+ isolate()->heap()->one_closure_cell_map(), *value),
+ FeedbackCell);
}
-Handle<Cell> Factory::NewManyClosuresCell(Handle<Object> value) {
- Handle<Cell> cell = NewCell(value);
- cell->set_map_no_write_barrier(*many_closures_cell_map());
- return cell;
+Handle<FeedbackCell> Factory::NewManyClosuresCell(Handle<HeapObject> value) {
+ AllowDeferredHandleDereference convert_to_cell;
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateFeedbackCell(
+ isolate()->heap()->many_closures_cell_map(), *value),
+ FeedbackCell);
}
Handle<PropertyCell> Factory::NewPropertyCell(Handle<Name> name) {
@@ -1423,8 +1473,10 @@ Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode,
HeapNumber);
}
-Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length) {
- CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateBigInt(length),
+Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length,
+ PretenureFlag pretenure) {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateBigInt(length, pretenure),
FreshlyAllocatedBigInt);
}
@@ -1519,7 +1571,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
function->set_shared(*info);
function->set_code(info->code());
function->set_context(*context_or_undefined);
- function->set_feedback_vector_cell(*undefined_cell());
+ function->set_feedback_cell(*many_closures_cell());
int header_size;
if (map->has_prototype_slot()) {
header_size = JSFunction::kSizeWithPrototype;
@@ -1664,11 +1716,11 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> info, Handle<Context> context,
- Handle<Cell> vector, PretenureFlag pretenure) {
+ Handle<FeedbackCell> feedback_cell, PretenureFlag pretenure) {
Handle<Map> initial_map(
Map::cast(context->native_context()->get(info->function_map_index())));
- return NewFunctionFromSharedFunctionInfo(initial_map, info, context, vector,
- pretenure);
+ return NewFunctionFromSharedFunctionInfo(initial_map, info, context,
+ feedback_cell, pretenure);
}
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
@@ -1688,29 +1740,29 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Handle<Map> initial_map, Handle<SharedFunctionInfo> info,
- Handle<Object> context_or_undefined, Handle<Cell> vector,
+ Handle<Object> context_or_undefined, Handle<FeedbackCell> feedback_cell,
PretenureFlag pretenure) {
DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
Handle<JSFunction> result =
NewFunction(initial_map, info, context_or_undefined, pretenure);
- // Bump the closure count that is encoded in the vector cell's map.
- if (vector->map() == *no_closures_cell_map()) {
- vector->set_map(*one_closure_cell_map());
- } else if (vector->map() == *one_closure_cell_map()) {
- vector->set_map(*many_closures_cell_map());
+ // Bump the closure count that is encoded in the feedback cell's map.
+ if (feedback_cell->map() == *no_closures_cell_map()) {
+ feedback_cell->set_map(*one_closure_cell_map());
+ } else if (feedback_cell->map() == *one_closure_cell_map()) {
+ feedback_cell->set_map(*many_closures_cell_map());
} else {
- DCHECK_EQ(vector->map(), *many_closures_cell_map());
+ DCHECK_EQ(feedback_cell->map(), *many_closures_cell_map());
}
- // Check that the optimized code in the feedback vector wasn't marked for
+ // Check that the optimized code in the feedback cell wasn't marked for
// deoptimization while not pointed to by any live JSFunction.
- if (vector->value()->IsFeedbackVector()) {
- FeedbackVector::cast(vector->value())
+ if (feedback_cell->value()->IsFeedbackVector()) {
+ FeedbackVector::cast(feedback_cell->value())
->EvictOptimizedCodeMarkedForDeoptimization(
*info, "new function from shared function info");
}
- result->set_feedback_vector_cell(*vector);
+ result->set_feedback_cell(*feedback_cell);
if (context_or_undefined->IsContext()) {
// Give compiler a chance to pre-initialize.
@@ -1759,17 +1811,13 @@ Handle<CodeDataContainer> Factory::NewCodeDataContainer(int flags) {
Handle<Code> Factory::NewCode(
const CodeDesc& desc, Code::Kind kind, Handle<Object> self_ref,
- int32_t builtin_index, MaybeHandle<HandlerTable> maybe_handler_table,
- MaybeHandle<ByteArray> maybe_source_position_table,
+ int32_t builtin_index, MaybeHandle<ByteArray> maybe_source_position_table,
MaybeHandle<DeoptimizationData> maybe_deopt_data, Movability movability,
uint32_t stub_key, bool is_turbofanned, int stack_slots,
- int safepoint_table_offset) {
+ int safepoint_table_offset, int handler_table_offset) {
Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
Handle<CodeDataContainer> data_container = NewCodeDataContainer(0);
- Handle<HandlerTable> handler_table =
- maybe_handler_table.is_null() ? HandlerTable::Empty(isolate())
- : maybe_handler_table.ToHandleChecked();
Handle<ByteArray> source_position_table =
maybe_source_position_table.is_null()
? empty_byte_array()
@@ -1778,13 +1826,13 @@ Handle<Code> Factory::NewCode(
maybe_deopt_data.is_null() ? DeoptimizationData::Empty(isolate())
: maybe_deopt_data.ToHandleChecked();
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateCode(
- desc, kind, self_ref, builtin_index, *reloc_info, *data_container,
- *handler_table, *source_position_table, *deopt_data, movability,
- stub_key, is_turbofanned, stack_slots, safepoint_table_offset),
- Code);
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateCode(
+ desc, kind, self_ref, builtin_index, *reloc_info,
+ *data_container, *source_position_table, *deopt_data,
+ movability, stub_key, is_turbofanned, stack_slots,
+ safepoint_table_offset, handler_table_offset),
+ Code);
}
Handle<Code> Factory::NewCodeForDeserialization(uint32_t size) {
@@ -2079,12 +2127,13 @@ Handle<JSIteratorResult> Factory::NewJSIteratorResult(Handle<Object> value,
}
Handle<JSAsyncFromSyncIterator> Factory::NewJSAsyncFromSyncIterator(
- Handle<JSReceiver> sync_iterator) {
+ Handle<JSReceiver> sync_iterator, Handle<Object> next) {
Handle<Map> map(isolate()->native_context()->async_from_sync_iterator_map());
Handle<JSAsyncFromSyncIterator> iterator =
Handle<JSAsyncFromSyncIterator>::cast(NewJSObjectFromMap(map));
iterator->set_sync_iterator(*sync_iterator);
+ iterator->set_next(*next);
return iterator;
}
@@ -2453,14 +2502,10 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
MaybeHandle<String> name, FunctionKind kind, Handle<Code> code,
Handle<ScopeInfo> scope_info) {
- DCHECK(IsValidFunctionKind(kind));
Handle<SharedFunctionInfo> shared =
NewSharedFunctionInfo(name, code, IsConstructable(kind), kind);
shared->set_scope_info(*scope_info);
shared->set_outer_scope_info(*the_hole_value());
- if (IsGeneratorFunction(kind)) {
- shared->set_instance_class_name(isolate()->heap()->Generator_string());
- }
return shared;
}
@@ -2530,13 +2575,10 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
is_constructor ? isolate()->builtins()->JSConstructStubGeneric()
: BUILTIN_CODE(isolate(), ConstructedNonConstructable);
share->SetConstructStub(*construct_stub);
- share->set_instance_class_name(*Object_string());
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
- StaticFeedbackVectorSpec empty_spec;
- Handle<FeedbackMetadata> feedback_metadata =
- FeedbackMetadata::New(isolate(), &empty_spec);
+ Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(isolate());
share->set_feedback_metadata(*feedback_metadata, SKIP_WRITE_BARRIER);
share->set_function_literal_id(FunctionLiteral::kIdTypeInvalid);
#if V8_SFI_HAS_UNIQUE_ID
@@ -2673,7 +2715,7 @@ Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
Handle<BreakPointInfo> new_break_point_info =
Handle<BreakPointInfo>::cast(NewStruct(TUPLE2_TYPE, TENURED));
new_break_point_info->set_source_position(source_position);
- new_break_point_info->set_break_point_objects(*undefined_value());
+ new_break_point_info->set_break_points(*undefined_value());
return new_break_point_info;
}
@@ -2701,7 +2743,7 @@ Handle<StackFrameInfo> Factory::NewStackFrameInfo() {
Handle<SourcePositionTableWithFrameCache>
Factory::NewSourcePositionTableWithFrameCache(
Handle<ByteArray> source_position_table,
- Handle<NumberDictionary> stack_frame_cache) {
+ Handle<SimpleNumberDictionary> stack_frame_cache) {
Handle<SourcePositionTableWithFrameCache>
source_position_table_with_frame_cache =
Handle<SourcePositionTableWithFrameCache>::cast(
@@ -3084,6 +3126,19 @@ Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) {
return map;
}
+Handle<JSPromise> Factory::NewJSPromiseWithoutHook(PretenureFlag pretenure) {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateJSPromise(
+ *isolate()->promise_function(), pretenure),
+ JSPromise);
+}
+
+Handle<JSPromise> Factory::NewJSPromise(PretenureFlag pretenure) {
+ Handle<JSPromise> promise = NewJSPromiseWithoutHook(pretenure);
+ isolate()->RunPromiseHook(PromiseHookType::kInit, promise, undefined_value());
+ return promise;
+}
+
// static
NewFunctionArgs NewFunctionArgs::ForWasm(Handle<String> name, Handle<Code> code,
Handle<Map> map) {