Reland of "Store SharedFunctionInfos of a Script in a FixedArray indexed by their ID"
Original CL description: > Store SharedFunctionInfos of a Script in a FixedArray indexed by their ID > > Now that SharedFunctionInfos have a unique ID (and the IDs are dense), > we can use them as an index into an array, instead of using a > WeakFixedArray where we have to do a linear scan. > > Hooking up liveedit is a bit more involved, see > https://docs.google.com/presentation/d/1FtNa3U7WsF5bPhY9uGoJG5Y9hnz5VBDabfOWpb4unWI/edit > for an overview > > BUG=v8:5589 > R=verwaest@chromium.org,jgruber@chromium.org > > Review-Url: https://codereview.chromium.org/2547483002 BUG=v8:5589 TBR=verwaest@chromium.org,jgruber@chromium.org Review-Url: https://codereview.chromium.org/2577063002 Cr-Commit-Position: refs/heads/master@{#41734}
This commit is contained in:
parent
c131dd9561
commit
4f2cb8fe82
@ -595,8 +595,11 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
|
||||
Handle<String> source = factory->NewStringFromStaticChars("() {}");
|
||||
Handle<Script> script = factory->NewScript(source);
|
||||
script->set_type(Script::TYPE_NATIVE);
|
||||
Handle<FixedArray> infos = factory->NewFixedArray(2);
|
||||
script->set_shared_function_infos(*infos);
|
||||
empty_function->shared()->set_start_position(0);
|
||||
empty_function->shared()->set_end_position(source->length());
|
||||
empty_function->shared()->set_function_literal_id(1);
|
||||
empty_function->shared()->DontAdaptArguments();
|
||||
SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
|
||||
|
||||
|
@ -460,12 +460,29 @@ bool CompileUnoptimizedCode(CompilationInfo* info) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) {
|
||||
DCHECK(info->is_toplevel());
|
||||
DCHECK(!info->script().is_null());
|
||||
if (info->script()->shared_function_infos()->length() > 0) {
|
||||
DCHECK_EQ(info->script()->shared_function_infos()->length(),
|
||||
info->max_function_literal_id() + 1);
|
||||
return;
|
||||
}
|
||||
Isolate* isolate = info->isolate();
|
||||
Handle<FixedArray> infos(
|
||||
isolate->factory()->NewFixedArray(info->max_function_literal_id() + 1));
|
||||
info->script()->set_shared_function_infos(*infos);
|
||||
}
|
||||
|
||||
MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) {
|
||||
VMState<COMPILER> state(info->isolate());
|
||||
PostponeInterruptsScope postpone(info->isolate());
|
||||
|
||||
// Parse and update CompilationInfo with the results.
|
||||
if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>();
|
||||
if (info->parse_info()->is_toplevel()) {
|
||||
EnsureSharedFunctionInfosArrayOnScript(info->parse_info());
|
||||
}
|
||||
DCHECK_EQ(info->shared_info()->language_mode(),
|
||||
info->literal()->language_mode());
|
||||
|
||||
@ -970,6 +987,8 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
return Handle<SharedFunctionInfo>::null();
|
||||
}
|
||||
|
||||
EnsureSharedFunctionInfosArrayOnScript(parse_info);
|
||||
|
||||
FunctionLiteral* lit = parse_info->literal();
|
||||
|
||||
// Measure how long it takes to do the compilation; only take the
|
||||
@ -1032,6 +1051,7 @@ bool Compiler::Analyze(ParseInfo* info) {
|
||||
|
||||
bool Compiler::ParseAndAnalyze(ParseInfo* info) {
|
||||
if (!parsing::ParseAny(info)) return false;
|
||||
if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info);
|
||||
if (!Compiler::Analyze(info)) return false;
|
||||
DCHECK_NOT_NULL(info->literal());
|
||||
DCHECK_NOT_NULL(info->scope());
|
||||
@ -1152,8 +1172,9 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
|
||||
// In order to ensure that live edit function info collection finds the newly
|
||||
// generated shared function infos, clear the script's list temporarily
|
||||
// and restore it at the end of this method.
|
||||
Handle<Object> old_function_infos(script->shared_function_infos(), isolate);
|
||||
script->set_shared_function_infos(Smi::kZero);
|
||||
Handle<FixedArray> old_function_infos(script->shared_function_infos(),
|
||||
isolate);
|
||||
script->set_shared_function_infos(isolate->heap()->empty_fixed_array());
|
||||
|
||||
// Start a compilation.
|
||||
Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
@ -1563,15 +1584,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
MaybeHandle<SharedFunctionInfo> maybe_existing;
|
||||
|
||||
// Find any previously allocated shared function info for the given literal.
|
||||
if (outer_info->shared_info()->never_compiled()) {
|
||||
// On the first compile, there are no existing shared function info for
|
||||
// inner functions yet, so do not try to find them. All bets are off for
|
||||
// live edit though.
|
||||
SLOW_DCHECK(script->FindSharedFunctionInfo(literal).is_null() ||
|
||||
isolate->debug()->live_edit_enabled());
|
||||
} else {
|
||||
maybe_existing = script->FindSharedFunctionInfo(literal);
|
||||
}
|
||||
maybe_existing = script->FindSharedFunctionInfo(isolate, literal);
|
||||
|
||||
// We found an existing shared function info. If it has any sort of code
|
||||
// attached, don't worry about compiling and simply return it. Otherwise,
|
||||
@ -1594,11 +1607,6 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
result =
|
||||
isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script);
|
||||
result->set_is_toplevel(false);
|
||||
|
||||
// If the outer function has been compiled before, we cannot be sure that
|
||||
// shared function info for this function literal has been created for the
|
||||
// first time. It may have already been compiled previously.
|
||||
result->set_never_compiled(outer_info->shared_info()->never_compiled());
|
||||
}
|
||||
|
||||
Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
|
@ -142,7 +142,6 @@ HCompilationJob::Status HCompilationJob::PrepareJobImpl() {
|
||||
}
|
||||
}
|
||||
DCHECK(info()->shared_info()->has_deoptimization_support());
|
||||
DCHECK(!info()->shared_info()->never_compiled());
|
||||
|
||||
// Check the whitelist for Crankshaft.
|
||||
if (!info()->shared_info()->PassesFilter(FLAG_hydrogen_filter)) {
|
||||
|
@ -1244,7 +1244,7 @@ bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
|
||||
// cover this, because the given function might have been inlined into code
|
||||
// for which no JSFunction exists.
|
||||
{
|
||||
SharedFunctionInfo::Iterator iterator(isolate_);
|
||||
SharedFunctionInfo::GlobalIterator iterator(isolate_);
|
||||
while (SharedFunctionInfo* shared = iterator.Next()) {
|
||||
shared->ClearCodeFromOptimizedCodeMap();
|
||||
}
|
||||
@ -1335,16 +1335,11 @@ void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position,
|
||||
bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
|
||||
int end_position, std::set<int>* positions) {
|
||||
while (true) {
|
||||
if (!script->shared_function_infos()->IsWeakFixedArray()) return false;
|
||||
|
||||
WeakFixedArray* infos =
|
||||
WeakFixedArray::cast(script->shared_function_infos());
|
||||
HandleScope scope(isolate_);
|
||||
List<Handle<SharedFunctionInfo>> candidates;
|
||||
{
|
||||
WeakFixedArray::Iterator iterator(infos);
|
||||
SharedFunctionInfo* info;
|
||||
while ((info = iterator.Next<SharedFunctionInfo>())) {
|
||||
SharedFunctionInfo::ScriptIterator iterator(script);
|
||||
for (SharedFunctionInfo* info = iterator.Next(); info != nullptr;
|
||||
info = iterator.Next()) {
|
||||
if (info->end_position() < start_position ||
|
||||
info->start_position() >= end_position) {
|
||||
continue;
|
||||
@ -1353,7 +1348,6 @@ bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
|
||||
if (!info->HasDebugCode() && !info->allows_lazy_compilation()) continue;
|
||||
candidates.Add(i::handle(info));
|
||||
}
|
||||
}
|
||||
|
||||
bool was_compiled = false;
|
||||
for (int i = 0; i < candidates.length(); ++i) {
|
||||
@ -1462,15 +1456,14 @@ Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
|
||||
// find the inner most function containing this position.
|
||||
// If there is no shared function info for this script at all, there is
|
||||
// no point in looking for it by walking the heap.
|
||||
if (!script->shared_function_infos()->IsWeakFixedArray()) break;
|
||||
|
||||
SharedFunctionInfo* shared;
|
||||
{
|
||||
SharedFunctionInfoFinder finder(position);
|
||||
WeakFixedArray::Iterator iterator(script->shared_function_infos());
|
||||
SharedFunctionInfo* candidate;
|
||||
while ((candidate = iterator.Next<SharedFunctionInfo>())) {
|
||||
finder.NewCandidate(candidate);
|
||||
SharedFunctionInfo::ScriptIterator iterator(script);
|
||||
for (SharedFunctionInfo* info = iterator.Next(); info != nullptr;
|
||||
info = iterator.Next()) {
|
||||
finder.NewCandidate(info);
|
||||
}
|
||||
shared = finder.Result();
|
||||
if (shared == NULL) break;
|
||||
|
@ -604,12 +604,9 @@ static int GetArrayLength(Handle<JSArray> array) {
|
||||
return Smi::cast(length)->value();
|
||||
}
|
||||
|
||||
|
||||
void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
|
||||
int start_position,
|
||||
int end_position, int param_num,
|
||||
int literal_count,
|
||||
int parent_index) {
|
||||
void FunctionInfoWrapper::SetInitialProperties(
|
||||
Handle<String> name, int start_position, int end_position, int param_num,
|
||||
int literal_count, int parent_index, int function_literal_id) {
|
||||
HandleScope scope(isolate());
|
||||
this->SetField(kFunctionNameOffset_, name);
|
||||
this->SetSmiValueField(kStartPositionOffset_, start_position);
|
||||
@ -617,6 +614,7 @@ void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
|
||||
this->SetSmiValueField(kParamNumOffset_, param_num);
|
||||
this->SetSmiValueField(kLiteralNumOffset_, literal_count);
|
||||
this->SetSmiValueField(kParentIndexOffset_, parent_index);
|
||||
this->SetSmiValueField(kFunctionLiteralIdOffset_, function_literal_id);
|
||||
}
|
||||
|
||||
void FunctionInfoWrapper::SetSharedFunctionInfo(
|
||||
@ -1038,15 +1036,36 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
isolate->compilation_cache()->Remove(shared_info);
|
||||
}
|
||||
|
||||
|
||||
void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array) {
|
||||
void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array,
|
||||
int new_function_literal_id) {
|
||||
SharedInfoWrapper shared_info_wrapper(shared_info_array);
|
||||
Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
|
||||
|
||||
shared_info->set_function_literal_id(new_function_literal_id);
|
||||
DeoptimizeDependentFunctions(*shared_info);
|
||||
shared_info_array->GetIsolate()->compilation_cache()->Remove(shared_info);
|
||||
}
|
||||
|
||||
void LiveEdit::FixupScript(Handle<Script> script, int max_function_literal_id) {
|
||||
Isolate* isolate = script->GetIsolate();
|
||||
Handle<FixedArray> old_infos(script->shared_function_infos(), isolate);
|
||||
Handle<FixedArray> new_infos(
|
||||
isolate->factory()->NewFixedArray(max_function_literal_id + 1));
|
||||
script->set_shared_function_infos(*new_infos);
|
||||
SharedFunctionInfo::ScriptIterator iterator(isolate, old_infos);
|
||||
while (SharedFunctionInfo* shared = iterator.Next()) {
|
||||
// We can't use SharedFunctionInfo::SetScript(info, undefined_value()) here,
|
||||
// as we severed the link from the Script to the SharedFunctionInfo above.
|
||||
Handle<SharedFunctionInfo> info(shared, isolate);
|
||||
info->set_script(isolate->heap()->undefined_value());
|
||||
Handle<Object> new_noscript_list = WeakFixedArray::Add(
|
||||
isolate->factory()->noscript_shared_function_infos(), info);
|
||||
isolate->heap()->SetRootNoScriptSharedFunctionInfos(*new_noscript_list);
|
||||
|
||||
// Put the SharedFunctionInfo at its new, correct location.
|
||||
SharedFunctionInfo::SetScript(info, script);
|
||||
}
|
||||
}
|
||||
|
||||
void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
|
||||
Handle<Object> script_handle) {
|
||||
@ -1173,6 +1192,10 @@ static Handle<Script> CreateScriptCopy(Handle<Script> original) {
|
||||
copy->set_eval_from_shared(original->eval_from_shared());
|
||||
copy->set_eval_from_position(original->eval_from_position());
|
||||
|
||||
Handle<FixedArray> infos(isolate->factory()->NewFixedArray(
|
||||
original->shared_function_infos()->length()));
|
||||
copy->set_shared_function_infos(*infos);
|
||||
|
||||
// Copy all the flags, but clear compilation state.
|
||||
copy->set_flags(original->flags());
|
||||
copy->set_compilation_state(Script::COMPILATION_STATE_INITIAL);
|
||||
@ -1180,7 +1203,6 @@ static Handle<Script> CreateScriptCopy(Handle<Script> original) {
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> LiveEdit::ChangeScriptSource(Handle<Script> original_script,
|
||||
Handle<String> new_source,
|
||||
Handle<Object> old_script_name) {
|
||||
@ -1856,10 +1878,8 @@ void LiveEditFunctionTracker::VisitFunctionLiteral(FunctionLiteral* node) {
|
||||
// Recurse using the regular traversal.
|
||||
AstTraversalVisitor::VisitFunctionLiteral(node);
|
||||
// FunctionDone are called in post-order.
|
||||
// TODO(jgruber): If required, replace the (linear cost)
|
||||
// FindSharedFunctionInfo call with a more efficient implementation.
|
||||
Handle<SharedFunctionInfo> info =
|
||||
script_->FindSharedFunctionInfo(node).ToHandleChecked();
|
||||
script_->FindSharedFunctionInfo(isolate_, node).ToHandleChecked();
|
||||
FunctionDone(info, node->scope());
|
||||
}
|
||||
|
||||
@ -1869,7 +1889,7 @@ void LiveEditFunctionTracker::FunctionStarted(FunctionLiteral* fun) {
|
||||
info.SetInitialProperties(fun->name(), fun->start_position(),
|
||||
fun->end_position(), fun->parameter_count(),
|
||||
fun->materialized_literal_count(),
|
||||
current_parent_index_);
|
||||
current_parent_index_, fun->function_literal_id());
|
||||
current_parent_index_ = len_;
|
||||
SetElementSloppy(result_, len_, info.GetJSArray());
|
||||
len_++;
|
||||
|
@ -83,7 +83,10 @@ class LiveEdit : AllStatic {
|
||||
static void ReplaceFunctionCode(Handle<JSArray> new_compile_info_array,
|
||||
Handle<JSArray> shared_info_array);
|
||||
|
||||
static void FunctionSourceUpdated(Handle<JSArray> shared_info_array);
|
||||
static void FixupScript(Handle<Script> script, int max_function_literal_id);
|
||||
|
||||
static void FunctionSourceUpdated(Handle<JSArray> shared_info_array,
|
||||
int new_function_literal_id);
|
||||
|
||||
// Updates script field in FunctionSharedInfo.
|
||||
static void SetFunctionScript(Handle<JSValue> function_wrapper,
|
||||
@ -278,7 +281,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
|
||||
void SetInitialProperties(Handle<String> name, int start_position,
|
||||
int end_position, int param_num, int literal_count,
|
||||
int parent_index);
|
||||
int parent_index, int function_literal_id);
|
||||
|
||||
void SetFunctionScopeInfo(Handle<Object> scope_info_array) {
|
||||
this->SetField(kFunctionScopeInfoOffset_, scope_info_array);
|
||||
@ -311,7 +314,8 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
static const int kParentIndexOffset_ = 5;
|
||||
static const int kSharedFunctionInfoOffset_ = 6;
|
||||
static const int kLiteralNumOffset_ = 7;
|
||||
static const int kSize_ = 8;
|
||||
static const int kFunctionLiteralIdOffset_ = 8;
|
||||
static const int kSize_ = 9;
|
||||
|
||||
friend class JSArrayBasedStruct<FunctionInfoWrapper>;
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
var FindScriptSourcePosition = global.Debug.findScriptSourcePosition;
|
||||
var GlobalArray = global.Array;
|
||||
var MathFloor = global.Math.floor;
|
||||
var MathMax = global.Math.max;
|
||||
var SyntaxError = global.SyntaxError;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -75,6 +76,10 @@
|
||||
}
|
||||
throw failure;
|
||||
}
|
||||
|
||||
var max_function_literal_id = new_compile_info.reduce(
|
||||
(max, info) => MathMax(max, info.function_literal_id), 0);
|
||||
|
||||
var root_new_node = BuildCodeInfoTree(new_compile_info);
|
||||
|
||||
// Link recompiled script data with other data.
|
||||
@ -177,8 +182,7 @@
|
||||
|
||||
// Update the script text and create a new script representing an old
|
||||
// version of the script.
|
||||
old_script = %LiveEditReplaceScript(script, new_source,
|
||||
old_script_name);
|
||||
old_script = %LiveEditReplaceScript(script, new_source, old_script_name);
|
||||
|
||||
var link_to_old_script_report = new GlobalArray();
|
||||
change_log.push( { linked_to_old_script: link_to_old_script_report } );
|
||||
@ -192,12 +196,6 @@
|
||||
preview_description.created_script_name = old_script_name;
|
||||
}
|
||||
|
||||
// Link to an actual script all the functions that we are going to use.
|
||||
for (var i = 0; i < link_to_original_script_list.length; i++) {
|
||||
%LiveEditFunctionSetScript(
|
||||
link_to_original_script_list[i].info.shared_function_info, script);
|
||||
}
|
||||
|
||||
for (var i = 0; i < replace_code_list.length; i++) {
|
||||
PatchFunctionCode(replace_code_list[i], change_log);
|
||||
}
|
||||
@ -212,13 +210,25 @@
|
||||
position_patch_report);
|
||||
|
||||
if (update_positions_list[i].live_shared_function_infos) {
|
||||
update_positions_list[i].live_shared_function_infos.
|
||||
forEach(function (info) {
|
||||
%LiveEditFunctionSourceUpdated(info.raw_array);
|
||||
var new_function_literal_id =
|
||||
update_positions_list[i]
|
||||
.corresponding_node.info.function_literal_id;
|
||||
update_positions_list[i].live_shared_function_infos.forEach(function(
|
||||
info) {
|
||||
%LiveEditFunctionSourceUpdated(
|
||||
info.raw_array, new_function_literal_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
%LiveEditFixupScript(script, max_function_literal_id);
|
||||
|
||||
// Link all the functions we're going to use to an actual script.
|
||||
for (var i = 0; i < link_to_original_script_list.length; i++) {
|
||||
%LiveEditFunctionSetScript(
|
||||
link_to_original_script_list[i].info.shared_function_info, script);
|
||||
}
|
||||
|
||||
preview_description.updated = true;
|
||||
return preview_description;
|
||||
}
|
||||
@ -658,6 +668,8 @@
|
||||
old_children[old_index].corresponding_node = UNDEFINED;
|
||||
old_node.status = FunctionStatus.CHANGED;
|
||||
}
|
||||
} else {
|
||||
ProcessNode(old_children[old_index], new_children[new_index]);
|
||||
}
|
||||
} else {
|
||||
old_children[old_index].status = FunctionStatus.DAMAGED;
|
||||
@ -761,6 +773,7 @@
|
||||
this.scope_info = raw_array[4];
|
||||
this.outer_index = raw_array[5];
|
||||
this.shared_function_info = raw_array[6];
|
||||
this.function_literal_id = raw_array[8];
|
||||
this.next_sibling_index = null;
|
||||
this.raw_array = raw_array;
|
||||
}
|
||||
|
@ -167,7 +167,6 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
|
||||
FixedArray);
|
||||
}
|
||||
|
||||
|
||||
Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
|
||||
CALL_HEAP_FUNCTION(
|
||||
isolate(),
|
||||
@ -1059,7 +1058,7 @@ Handle<Script> Factory::NewScript(Handle<String> source) {
|
||||
script->set_line_ends(heap->undefined_value());
|
||||
script->set_eval_from_shared(heap->undefined_value());
|
||||
script->set_eval_from_position(0);
|
||||
script->set_shared_function_infos(Smi::kZero);
|
||||
script->set_shared_function_infos(*empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
script->set_flags(0);
|
||||
|
||||
heap->set_script_list(*WeakFixedArray::Add(script_list(), script));
|
||||
|
@ -5800,8 +5800,6 @@ void Heap::CompactWeakFixedArrays() {
|
||||
WeakFixedArray* array = WeakFixedArray::cast(prototype_users);
|
||||
array->Compact<JSObject::PrototypeRegistryCompactionCallback>();
|
||||
}
|
||||
} else if (o->IsScript()) {
|
||||
CompactWeakFixedArray(Script::cast(o)->shared_function_infos());
|
||||
}
|
||||
}
|
||||
CompactWeakFixedArray(noscript_shared_function_infos());
|
||||
|
@ -441,10 +441,8 @@ void ObjectStatsCollector::RecordJSCollectionDetails(JSObject* obj) {
|
||||
}
|
||||
|
||||
void ObjectStatsCollector::RecordScriptDetails(Script* obj) {
|
||||
Object* infos = WeakFixedArray::cast(obj->shared_function_infos());
|
||||
if (infos->IsWeakFixedArray())
|
||||
RecordFixedArrayHelper(obj, WeakFixedArray::cast(infos),
|
||||
SHARED_FUNCTION_INFOS_SUB_TYPE, 0);
|
||||
FixedArray* infos = FixedArray::cast(obj->shared_function_infos());
|
||||
RecordFixedArrayHelper(obj, infos, SHARED_FUNCTION_INFOS_SUB_TYPE, 0);
|
||||
}
|
||||
|
||||
void ObjectStatsCollector::RecordMapDetails(Map* map_obj) {
|
||||
|
@ -363,7 +363,7 @@ utils.InstallGetter(GlobalPromise, speciesSymbol, PromiseSpecies);
|
||||
%SetCode(GlobalPromise.prototype.catch, PromiseCatch);
|
||||
|
||||
%InstallToContext([
|
||||
"promise_catch", PromiseCatch,
|
||||
"promise_catch", GlobalPromise.prototype.catch,
|
||||
"promise_create", PromiseCreate,
|
||||
"promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler,
|
||||
"promise_reject", DoRejectPromise,
|
||||
|
@ -5962,7 +5962,7 @@ ACCESSORS_CHECKED(Script, eval_from_shared, Object, kEvalFromSharedOffset,
|
||||
this->type() != TYPE_WASM)
|
||||
SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset,
|
||||
this->type() != TYPE_WASM)
|
||||
ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
|
||||
ACCESSORS(Script, shared_function_infos, FixedArray, kSharedFunctionInfosOffset)
|
||||
SMI_ACCESSORS(Script, flags, kFlagsOffset)
|
||||
ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
|
||||
ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
|
||||
@ -6078,8 +6078,6 @@ BOOL_ACCESSORS(SharedFunctionInfo,
|
||||
kHasDuplicateParameters)
|
||||
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
|
||||
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, deserialized, kDeserialized)
|
||||
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, never_compiled,
|
||||
kNeverCompiled)
|
||||
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_declaration,
|
||||
kIsDeclaration)
|
||||
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, marked_for_tier_up,
|
||||
@ -6300,8 +6298,6 @@ void SharedFunctionInfo::ReplaceCode(Code* value) {
|
||||
#endif // DEBUG
|
||||
|
||||
set_code(value);
|
||||
|
||||
if (is_compiled()) set_never_compiled(false);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::IsInterpreted() const {
|
||||
|
111
src/objects.cc
111
src/objects.cc
@ -13645,23 +13645,16 @@ Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
||||
FunctionLiteral* fun) {
|
||||
WeakFixedArray::Iterator iterator(shared_function_infos());
|
||||
SharedFunctionInfo* shared;
|
||||
while ((shared = iterator.Next<SharedFunctionInfo>())) {
|
||||
if (fun->function_token_position() == shared->function_token_position() &&
|
||||
fun->start_position() == shared->start_position() &&
|
||||
fun->end_position() == shared->end_position()) {
|
||||
DCHECK_EQ(fun->function_literal_id(), shared->function_literal_id());
|
||||
return Handle<SharedFunctionInfo>(shared);
|
||||
}
|
||||
DCHECK_NE(fun->function_literal_id(), shared->function_literal_id());
|
||||
}
|
||||
Isolate* isolate, FunctionLiteral* fun) {
|
||||
DCHECK_NE(fun->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
|
||||
DCHECK_LT(fun->function_literal_id(), shared_function_infos()->length());
|
||||
Object* shared = shared_function_infos()->get(fun->function_literal_id());
|
||||
if (shared->IsUndefined(isolate) || WeakCell::cast(shared)->cleared()) {
|
||||
return MaybeHandle<SharedFunctionInfo>();
|
||||
}
|
||||
|
||||
return handle(SharedFunctionInfo::cast(WeakCell::cast(shared)->value()));
|
||||
}
|
||||
|
||||
Script::Iterator::Iterator(Isolate* isolate)
|
||||
: iterator_(isolate->heap()->script_list()) {}
|
||||
@ -13669,31 +13662,51 @@ Script::Iterator::Iterator(Isolate* isolate)
|
||||
|
||||
Script* Script::Iterator::Next() { return iterator_.Next<Script>(); }
|
||||
|
||||
SharedFunctionInfo::ScriptIterator::ScriptIterator(Handle<Script> script)
|
||||
: ScriptIterator(script->GetIsolate(),
|
||||
handle(script->shared_function_infos())) {}
|
||||
|
||||
SharedFunctionInfo::Iterator::Iterator(Isolate* isolate)
|
||||
: script_iterator_(isolate),
|
||||
sfi_iterator_(isolate->heap()->noscript_shared_function_infos()) {}
|
||||
SharedFunctionInfo::ScriptIterator::ScriptIterator(
|
||||
Isolate* isolate, Handle<FixedArray> shared_function_infos)
|
||||
: isolate_(isolate),
|
||||
shared_function_infos_(shared_function_infos),
|
||||
index_(0) {}
|
||||
|
||||
|
||||
bool SharedFunctionInfo::Iterator::NextScript() {
|
||||
Script* script = script_iterator_.Next();
|
||||
if (script == NULL) return false;
|
||||
sfi_iterator_.Reset(script->shared_function_infos());
|
||||
return true;
|
||||
SharedFunctionInfo* SharedFunctionInfo::ScriptIterator::Next() {
|
||||
while (index_ < shared_function_infos_->length()) {
|
||||
Object* raw = shared_function_infos_->get(index_++);
|
||||
if (raw->IsUndefined(isolate_) || WeakCell::cast(raw)->cleared()) continue;
|
||||
return SharedFunctionInfo::cast(WeakCell::cast(raw)->value());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ScriptIterator::Reset(Handle<Script> script) {
|
||||
shared_function_infos_ = handle(script->shared_function_infos());
|
||||
index_ = 0;
|
||||
}
|
||||
|
||||
SharedFunctionInfo* SharedFunctionInfo::Iterator::Next() {
|
||||
do {
|
||||
SharedFunctionInfo* next = sfi_iterator_.Next<SharedFunctionInfo>();
|
||||
if (next != NULL) return next;
|
||||
} while (NextScript());
|
||||
return NULL;
|
||||
SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
|
||||
: script_iterator_(isolate),
|
||||
noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
|
||||
sfi_iterator_(handle(script_iterator_.Next(), isolate)) {}
|
||||
|
||||
SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() {
|
||||
SharedFunctionInfo* next = noscript_sfi_iterator_.Next<SharedFunctionInfo>();
|
||||
if (next != nullptr) return next;
|
||||
for (;;) {
|
||||
next = sfi_iterator_.Next();
|
||||
if (next != nullptr) return next;
|
||||
Script* next_script = script_iterator_.Next();
|
||||
if (next_script == nullptr) return nullptr;
|
||||
sfi_iterator_.Reset(handle(next_script));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
|
||||
Handle<Object> script_object) {
|
||||
DCHECK_NE(shared->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
|
||||
if (shared->script() == *script_object) return;
|
||||
Isolate* isolate = shared->GetIsolate();
|
||||
|
||||
@ -13701,13 +13714,22 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
|
||||
// the shared function info may be temporarily in two lists.
|
||||
// This is okay because the gc-time processing of these lists can tolerate
|
||||
// duplicates.
|
||||
Handle<Object> list;
|
||||
if (script_object->IsScript()) {
|
||||
Handle<Script> script = Handle<Script>::cast(script_object);
|
||||
list = handle(script->shared_function_infos(), isolate);
|
||||
} else {
|
||||
list = isolate->factory()->noscript_shared_function_infos();
|
||||
Handle<FixedArray> list = handle(script->shared_function_infos(), isolate);
|
||||
#ifdef DEBUG
|
||||
DCHECK_LT(shared->function_literal_id(), list->length());
|
||||
if (list->get(shared->function_literal_id())->IsWeakCell() &&
|
||||
!WeakCell::cast(list->get(shared->function_literal_id()))->cleared()) {
|
||||
DCHECK(
|
||||
WeakCell::cast(list->get(shared->function_literal_id()))->value() ==
|
||||
*shared);
|
||||
}
|
||||
#endif
|
||||
Handle<WeakCell> cell = isolate->factory()->NewWeakCell(shared);
|
||||
list->set(shared->function_literal_id(), *cell);
|
||||
} else {
|
||||
Handle<Object> list = isolate->factory()->noscript_shared_function_infos();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (FLAG_enable_slow_asserts) {
|
||||
@ -13718,22 +13740,26 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
|
||||
}
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
list = WeakFixedArray::Add(list, shared);
|
||||
|
||||
if (script_object->IsScript()) {
|
||||
Handle<Script> script = Handle<Script>::cast(script_object);
|
||||
script->set_shared_function_infos(*list);
|
||||
} else {
|
||||
isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list);
|
||||
}
|
||||
|
||||
// Remove shared function info from old script's list.
|
||||
if (shared->script()->IsScript()) {
|
||||
// Remove shared function info from old script's list.
|
||||
Script* old_script = Script::cast(shared->script());
|
||||
if (old_script->shared_function_infos()->IsWeakFixedArray()) {
|
||||
WeakFixedArray* list =
|
||||
WeakFixedArray::cast(old_script->shared_function_infos());
|
||||
list->Remove(shared);
|
||||
|
||||
// Due to liveedit, it might happen that the old_script doesn't know
|
||||
// about the SharedFunctionInfo, so we have to guard against that.
|
||||
Handle<FixedArray> infos(old_script->shared_function_infos(), isolate);
|
||||
if (shared->function_literal_id() < infos->length()) {
|
||||
Object* raw = old_script->shared_function_infos()->get(
|
||||
shared->function_literal_id());
|
||||
if (!raw->IsWeakCell() || WeakCell::cast(raw)->value() == *shared) {
|
||||
old_script->shared_function_infos()->set(
|
||||
shared->function_literal_id(), isolate->heap()->undefined_value());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove shared function info from root array.
|
||||
@ -13998,7 +14024,6 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
shared_info->set_uses_arguments(lit->scope()->arguments() != NULL);
|
||||
shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
|
||||
shared_info->set_is_function(lit->is_function());
|
||||
shared_info->set_never_compiled(true);
|
||||
shared_info->set_kind(lit->kind());
|
||||
if (!IsConstructable(lit->kind(), lit->language_mode())) {
|
||||
shared_info->SetConstructStub(
|
||||
|
@ -7127,7 +7127,7 @@ class Script: public Struct {
|
||||
|
||||
// [shared_function_infos]: weak fixed array containing all shared
|
||||
// function infos created from this script.
|
||||
DECL_ACCESSORS(shared_function_infos, Object)
|
||||
DECL_ACCESSORS(shared_function_infos, FixedArray)
|
||||
|
||||
// [flags]: Holds an exciting bitfield.
|
||||
DECL_INT_ACCESSORS(flags)
|
||||
@ -7212,7 +7212,8 @@ class Script: public Struct {
|
||||
|
||||
// Look through the list of existing shared function infos to find one
|
||||
// that matches the function literal. Return empty handle if not found.
|
||||
MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(FunctionLiteral* fun);
|
||||
MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(Isolate* isolate,
|
||||
FunctionLiteral* fun);
|
||||
|
||||
// Iterate over all script objects on the heap.
|
||||
class Iterator {
|
||||
@ -7740,9 +7741,6 @@ class SharedFunctionInfo: public HeapObject {
|
||||
// Indicates that the the shared function info is deserialized from cache.
|
||||
DECL_BOOLEAN_ACCESSORS(deserialized)
|
||||
|
||||
// Indicates that the the shared function info has never been compiled before.
|
||||
DECL_BOOLEAN_ACCESSORS(never_compiled)
|
||||
|
||||
// Whether this function was created from a FunctionDeclaration.
|
||||
DECL_BOOLEAN_ACCESSORS(is_declaration)
|
||||
|
||||
@ -7830,19 +7828,35 @@ class SharedFunctionInfo: public HeapObject {
|
||||
|
||||
void ResetForNewContext(int new_ic_age);
|
||||
|
||||
// Iterate over all shared function infos.
|
||||
class Iterator {
|
||||
// Iterate over all shared function infos in a given script.
|
||||
class ScriptIterator {
|
||||
public:
|
||||
explicit Iterator(Isolate* isolate);
|
||||
explicit ScriptIterator(Handle<Script> script);
|
||||
ScriptIterator(Isolate* isolate, Handle<FixedArray> shared_function_infos);
|
||||
SharedFunctionInfo* Next();
|
||||
|
||||
// Reset the iterator to run on |script|.
|
||||
void Reset(Handle<Script> script);
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
Handle<FixedArray> shared_function_infos_;
|
||||
int index_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
|
||||
};
|
||||
|
||||
// Iterate over all shared function infos on the heap.
|
||||
class GlobalIterator {
|
||||
public:
|
||||
explicit GlobalIterator(Isolate* isolate);
|
||||
SharedFunctionInfo* Next();
|
||||
|
||||
private:
|
||||
bool NextScript();
|
||||
|
||||
Script::Iterator script_iterator_;
|
||||
WeakFixedArray::Iterator sfi_iterator_;
|
||||
WeakFixedArray::Iterator noscript_sfi_iterator_;
|
||||
SharedFunctionInfo::ScriptIterator sfi_iterator_;
|
||||
DisallowHeapAllocation no_gc_;
|
||||
DISALLOW_COPY_AND_ASSIGN(Iterator);
|
||||
DISALLOW_COPY_AND_ASSIGN(GlobalIterator);
|
||||
};
|
||||
|
||||
DECLARE_CAST(SharedFunctionInfo)
|
||||
@ -8002,7 +8016,7 @@ class SharedFunctionInfo: public HeapObject {
|
||||
kAllowLazyCompilation,
|
||||
kMarkedForTierUp,
|
||||
kOptimizationDisabled,
|
||||
kNeverCompiled,
|
||||
kIsClassFieldInitializer,
|
||||
kNative,
|
||||
kStrictModeFunction,
|
||||
kUsesArguments,
|
||||
@ -8024,7 +8038,6 @@ class SharedFunctionInfo: public HeapObject {
|
||||
kIsDeclaration,
|
||||
kIsAsmWasmBroken,
|
||||
kRequiresClassFieldInit,
|
||||
kIsClassFieldInitializer,
|
||||
kCompilerHintsCount, // Pseudo entry
|
||||
};
|
||||
// kFunctionKind has to be byte-aligned
|
||||
|
@ -27,6 +27,7 @@ ParseInfo::ParseInfo(Zone* zone)
|
||||
start_position_(0),
|
||||
end_position_(0),
|
||||
function_literal_id_(FunctionLiteral::kIdTypeInvalid),
|
||||
max_function_literal_id_(FunctionLiteral::kIdTypeInvalid),
|
||||
isolate_(nullptr),
|
||||
cached_data_(nullptr),
|
||||
ast_value_factory_(nullptr),
|
||||
|
@ -154,6 +154,11 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
function_literal_id_ = function_literal_id;
|
||||
}
|
||||
|
||||
int max_function_literal_id() const { return max_function_literal_id_; }
|
||||
void set_max_function_literal_id(int max_function_literal_id) {
|
||||
max_function_literal_id_ = max_function_literal_id;
|
||||
}
|
||||
|
||||
// Getters for individual compiler hints.
|
||||
bool is_declaration() const;
|
||||
bool requires_class_field_init() const;
|
||||
@ -236,6 +241,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
int start_position_;
|
||||
int end_position_;
|
||||
int function_literal_id_;
|
||||
int max_function_literal_id_;
|
||||
|
||||
// TODO(titzer): Move handles and isolate out of ParseInfo.
|
||||
Isolate* isolate_;
|
||||
|
@ -809,6 +809,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
||||
}
|
||||
}
|
||||
|
||||
info->set_max_function_literal_id(GetLastFunctionLiteralId());
|
||||
|
||||
// Make sure the target stack is empty.
|
||||
DCHECK(target_stack_ == NULL);
|
||||
|
||||
|
@ -204,8 +204,13 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
|
||||
target_shared->set_native(was_native);
|
||||
target_shared->set_profiler_ticks(source_shared->profiler_ticks());
|
||||
target_shared->set_function_literal_id(source_shared->function_literal_id());
|
||||
SharedFunctionInfo::SetScript(
|
||||
target_shared, Handle<Object>(source_shared->script(), isolate));
|
||||
|
||||
Handle<Object> source_script(source_shared->script(), isolate);
|
||||
if (source_script->IsScript()) {
|
||||
SharedFunctionInfo::SetScript(source_shared,
|
||||
isolate->factory()->undefined_value());
|
||||
}
|
||||
SharedFunctionInfo::SetScript(target_shared, source_script);
|
||||
|
||||
// Set the code of the target function.
|
||||
target->ReplaceCode(source_shared->code());
|
||||
|
@ -100,15 +100,31 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
|
||||
}
|
||||
}
|
||||
|
||||
// Recreate the shared function infos array after changing the IDs of all
|
||||
// SharedFunctionInfos.
|
||||
RUNTIME_FUNCTION(Runtime_LiveEditFixupScript) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK(isolate->debug()->live_edit_enabled());
|
||||
DCHECK_EQ(args.length(), 2);
|
||||
CONVERT_ARG_CHECKED(JSValue, script_value, 0);
|
||||
CONVERT_INT32_ARG_CHECKED(max_function_literal_id, 1);
|
||||
|
||||
CHECK(script_value->value()->IsScript());
|
||||
Handle<Script> script(Script::cast(script_value->value()));
|
||||
|
||||
LiveEdit::FixupScript(script, max_function_literal_id);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK(isolate->debug()->live_edit_enabled());
|
||||
DCHECK(args.length() == 1);
|
||||
DCHECK_EQ(args.length(), 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
|
||||
CONVERT_INT32_ARG_CHECKED(new_function_literal_id, 1);
|
||||
CHECK(SharedInfoWrapper::IsInstance(shared_info));
|
||||
|
||||
LiveEdit::FunctionSourceUpdated(shared_info);
|
||||
LiveEdit::FunctionSourceUpdated(shared_info, new_function_literal_id);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
@ -346,13 +346,13 @@ namespace internal {
|
||||
F(CreateArrayLiteral, 4, 1) \
|
||||
F(CreateArrayLiteralStubBailout, 3, 1)
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC_LIVEEDIT(F) \
|
||||
F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \
|
||||
F(LiveEditGatherCompileInfo, 2, 1) \
|
||||
F(LiveEditReplaceScript, 3, 1) \
|
||||
F(LiveEditFunctionSourceUpdated, 1, 1) \
|
||||
F(LiveEditFunctionSourceUpdated, 2, 1) \
|
||||
F(LiveEditReplaceFunctionCode, 2, 1) \
|
||||
F(LiveEditFixupScript, 2, 1) \
|
||||
F(LiveEditFunctionSetScript, 2, 1) \
|
||||
F(LiveEditReplaceRefToNestedFunction, 3, 1) \
|
||||
F(LiveEditPatchFunctionPositions, 2, 1) \
|
||||
|
@ -6398,7 +6398,7 @@ TEST(SharedFunctionInfoIterator) {
|
||||
}
|
||||
|
||||
{
|
||||
SharedFunctionInfo::Iterator iterator(isolate);
|
||||
SharedFunctionInfo::GlobalIterator iterator(isolate);
|
||||
while (iterator.Next()) sfi_count--;
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,9 @@ void GetTopLevelFunctionInfo(
|
||||
Handle<JSFunction> toplevel_fn = v8::Utils::OpenHandle(*script);
|
||||
Handle<Script> i_script =
|
||||
handle(Script::cast(toplevel_fn->shared()->script()));
|
||||
SharedFunctionInfo::ScriptIterator iterator(i_script);
|
||||
|
||||
WeakFixedArray::Iterator iter(i_script->shared_function_infos());
|
||||
while (SharedFunctionInfo* shared = iter.Next<SharedFunctionInfo>()) {
|
||||
while (SharedFunctionInfo* shared = iterator.Next()) {
|
||||
std::unique_ptr<char[]> name = String::cast(shared->name())->ToCString();
|
||||
is_compiled->insert(std::make_pair(name.get(), shared->is_compiled()));
|
||||
}
|
||||
|
@ -1806,10 +1806,10 @@ TEST(CodeSerializerEagerCompilationAndPreAge) {
|
||||
HandleScope i_scope(i_isolate);
|
||||
Handle<SharedFunctionInfo> toplevel = v8::Utils::OpenHandle(*unbound);
|
||||
Handle<Script> script(Script::cast(toplevel->script()));
|
||||
WeakFixedArray::Iterator iterator(script->shared_function_infos());
|
||||
// Every function has been pre-compiled from the code cache.
|
||||
int count = 0;
|
||||
while (SharedFunctionInfo* shared = iterator.Next<SharedFunctionInfo>()) {
|
||||
SharedFunctionInfo::ScriptIterator iterator(script);
|
||||
while (SharedFunctionInfo* shared = iterator.Next()) {
|
||||
CHECK(shared->is_compiled());
|
||||
CHECK_EQ(Code::kPreAgedCodeAge, shared->code()->GetAge());
|
||||
count++;
|
||||
|
@ -91,13 +91,15 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
|
||||
source = isolate->factory()->NewStringFromAsciiChecked(test_script);
|
||||
}
|
||||
Handle<Script> script = isolate->factory()->NewScript(source);
|
||||
Handle<FixedArray> infos = isolate->factory()->NewFixedArray(3);
|
||||
script->set_shared_function_infos(*infos);
|
||||
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
|
||||
isolate->factory()->NewStringFromAsciiChecked("f"),
|
||||
isolate->builtins()->CompileLazy(), false);
|
||||
SharedFunctionInfo::SetScript(shared, script);
|
||||
shared->set_end_position(source->length());
|
||||
shared->set_outer_scope_info(ScopeInfo::Empty(isolate));
|
||||
shared->set_function_literal_id(1);
|
||||
SharedFunctionInfo::SetScript(shared, script);
|
||||
return scope.CloseAndEscape(shared);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user