Commit ceb9c812 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[sfi] Remove SFI function literal id field

SharedFunctionInfos store their original function literal's id. This is
also their index in the Script's SFI list.

Since the function literal id is only needed for lazy compilation and live
edit, we can calculate it on-the-fly by linear search in the Script SFI list,
and save a field on the SFI.

If this regresses compile performance, we could alternatively store the
function literal id on the preparsed scope data as future work.

Bug: chromium:818642
Change-Id: I5468cea0e115921f1c864d94e567d749a4349882
Reviewed-on: https://chromium-review.googlesource.com/1082480
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53523}
parent e3190c21
...@@ -620,10 +620,9 @@ Handle<JSFunction> Genesis::CreateEmptyFunction() { ...@@ -620,10 +620,9 @@ Handle<JSFunction> Genesis::CreateEmptyFunction() {
empty_function->shared()->set_raw_start_position(0); empty_function->shared()->set_raw_start_position(0);
empty_function->shared()->set_raw_end_position(source->length()); empty_function->shared()->set_raw_end_position(source->length());
empty_function->shared()->set_scope_info(*scope_info); empty_function->shared()->set_scope_info(*scope_info);
empty_function->shared()->set_function_literal_id(1);
empty_function->shared()->DontAdaptArguments(); empty_function->shared()->DontAdaptArguments();
SharedFunctionInfo::SetScript(handle(empty_function->shared(), isolate()), SharedFunctionInfo::SetScript(handle(empty_function->shared(), isolate()),
script); script, 1);
return empty_function; return empty_function;
} }
......
...@@ -197,7 +197,7 @@ void UnoptimizedCompileJob::PrepareOnMainThread(Isolate* isolate) { ...@@ -197,7 +197,7 @@ void UnoptimizedCompileJob::PrepareOnMainThread(Isolate* isolate) {
parse_info_->set_end_position(shared_->EndPosition()); parse_info_->set_end_position(shared_->EndPosition());
parse_info_->set_unicode_cache(unicode_cache_.get()); parse_info_->set_unicode_cache(unicode_cache_.get());
parse_info_->set_language_mode(shared_->language_mode()); parse_info_->set_language_mode(shared_->language_mode());
parse_info_->set_function_literal_id(shared_->function_literal_id()); parse_info_->set_function_literal_id(shared_->GetFunctionLiteralId(isolate));
if (V8_UNLIKELY(FLAG_runtime_stats)) { if (V8_UNLIKELY(FLAG_runtime_stats)) {
parse_info_->set_runtime_call_stats(new (parse_info_->zone()) parse_info_->set_runtime_call_stats(new (parse_info_->zone())
RuntimeCallStats()); RuntimeCallStats());
......
...@@ -863,12 +863,14 @@ void LiveEdit::ReplaceFunctionCode( ...@@ -863,12 +863,14 @@ void LiveEdit::ReplaceFunctionCode(
} }
void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array, void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array,
Handle<Script> script,
int new_function_literal_id) { int new_function_literal_id) {
SharedInfoWrapper shared_info_wrapper(shared_info_array); SharedInfoWrapper shared_info_wrapper(shared_info_array);
Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
shared_info->set_function_literal_id(new_function_literal_id);
shared_info_array->GetIsolate()->debug()->DeoptimizeFunction(shared_info); shared_info_array->GetIsolate()->debug()->DeoptimizeFunction(shared_info);
SharedFunctionInfo::SetScript(shared_info, script, new_function_literal_id);
} }
void LiveEdit::FixupScript(Handle<Script> script, int max_function_literal_id) { void LiveEdit::FixupScript(Handle<Script> script, int max_function_literal_id) {
...@@ -888,17 +890,20 @@ void LiveEdit::FixupScript(Handle<Script> script, int max_function_literal_id) { ...@@ -888,17 +890,20 @@ void LiveEdit::FixupScript(Handle<Script> script, int max_function_literal_id) {
isolate->heap()->SetRootNoScriptSharedFunctionInfos(*new_noscript_list); isolate->heap()->SetRootNoScriptSharedFunctionInfos(*new_noscript_list);
// Put the SharedFunctionInfo at its new, correct location. // Put the SharedFunctionInfo at its new, correct location.
SharedFunctionInfo::SetScript(info, script); SharedFunctionInfo::SetScript(info, script, iterator.CurrentIndex());
} }
} }
void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper,
Handle<Object> script_handle) { Handle<Object> script_handle,
int function_literal_id) {
Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo> shared_info =
UnwrapSharedFunctionInfoFromJSValue(function_wrapper); UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
Isolate* isolate = function_wrapper->GetIsolate(); Isolate* isolate = function_wrapper->GetIsolate();
CHECK(script_handle->IsScript() || script_handle->IsUndefined(isolate)); CHECK(script_handle->IsScript() || script_handle->IsUndefined(isolate));
SharedFunctionInfo::SetScript(shared_info, script_handle); CHECK_IMPLIES(script_handle->IsScript(), function_literal_id >= 0);
SharedFunctionInfo::SetScript(shared_info, script_handle,
function_literal_id);
shared_info->DisableOptimization(BailoutReason::kLiveEdit); shared_info->DisableOptimization(BailoutReason::kLiveEdit);
function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info); function_wrapper->GetIsolate()->compilation_cache()->Remove(shared_info);
......
...@@ -85,11 +85,13 @@ class LiveEdit : AllStatic { ...@@ -85,11 +85,13 @@ class LiveEdit : AllStatic {
static void FixupScript(Handle<Script> script, int max_function_literal_id); static void FixupScript(Handle<Script> script, int max_function_literal_id);
static void FunctionSourceUpdated(Handle<JSArray> shared_info_array, static void FunctionSourceUpdated(Handle<JSArray> shared_info_array,
Handle<Script> script,
int new_function_literal_id); int new_function_literal_id);
// Updates script field in FunctionSharedInfo. // Updates script field in FunctionSharedInfo.
static void SetFunctionScript(Handle<JSValue> function_wrapper, static void SetFunctionScript(Handle<JSValue> function_wrapper,
Handle<Object> script_handle); Handle<Object> script_handle,
int function_literal_id);
static void PatchFunctionPositions(Handle<JSArray> shared_info_array, static void PatchFunctionPositions(Handle<JSArray> shared_info_array,
Handle<JSArray> position_change_array); Handle<JSArray> position_change_array);
......
...@@ -207,6 +207,8 @@ ...@@ -207,6 +207,8 @@
var position_patch_report = new GlobalArray(); var position_patch_report = new GlobalArray();
change_log.push( {position_patched: position_patch_report} ); change_log.push( {position_patched: position_patch_report} );
%LiveEditResizeScriptFunctionArray(script, max_function_literal_id);
for (var i = 0; i < update_positions_list.length; i++) { for (var i = 0; i < update_positions_list.length; i++) {
// TODO(LiveEdit): take into account whether it's source_changed or // TODO(LiveEdit): take into account whether it's source_changed or
// unchanged and whether positions changed at all. // unchanged and whether positions changed at all.
...@@ -220,17 +222,16 @@ ...@@ -220,17 +222,16 @@
update_positions_list[i].live_shared_function_infos.forEach(function( update_positions_list[i].live_shared_function_infos.forEach(function(
info) { info) {
%LiveEditFunctionSourceUpdated( %LiveEditFunctionSourceUpdated(
info.raw_array, new_function_literal_id); info.raw_array, script, new_function_literal_id);
}); });
} }
} }
%LiveEditFixupScript(script, max_function_literal_id);
// Link all the functions we're going to use to an actual script. // 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++) { for (var i = 0; i < link_to_original_script_list.length; i++) {
%LiveEditFunctionSetScript( %LiveEditFunctionSetScript(
link_to_original_script_list[i].info.shared_function_info, script); link_to_original_script_list[i].info.shared_function_info, script,
link_to_original_script_list[i].info.function_literal_id);
} }
preview_description.updated = true; preview_description.updated = true;
...@@ -260,7 +261,8 @@ ...@@ -260,7 +261,8 @@
// LiveEdit itself believe that any function in heap that points to a // LiveEdit itself believe that any function in heap that points to a
// particular script is a regular function. // particular script is a regular function.
// For some functions we will restore this link later. // For some functions we will restore this link later.
%LiveEditFunctionSetScript(info.shared_function_info, UNDEFINED); %LiveEditFunctionSetScript(info.shared_function_info, UNDEFINED,
info.function_literal_id);
compile_info.push(info); compile_info.push(info);
old_index_map.push(i); old_index_map.push(i);
} }
...@@ -359,9 +361,12 @@ ...@@ -359,9 +361,12 @@
// may access its own text. // may access its own text.
function LinkToOldScript(old_info_node, old_script, report_array) { function LinkToOldScript(old_info_node, old_script, report_array) {
if (old_info_node.live_shared_function_infos) { if (old_info_node.live_shared_function_infos) {
// TODO(leszeks): Passing "null" here as a marker that we should calculate
// the SFI's function literal id is ugly, it'd be better if this
// information was e.g. already on the info object.
old_info_node.live_shared_function_infos. old_info_node.live_shared_function_infos.
forEach(function (info) { forEach(function (info) {
%LiveEditFunctionSetScript(info.info, old_script); %LiveEditFunctionSetScript(info.info, old_script, null);
}); });
report_array.push( { name: old_info_node.info.function_name } ); report_array.push( { name: old_info_node.info.function_name } );
......
...@@ -3313,7 +3313,8 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral( ...@@ -3313,7 +3313,8 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral(
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfoForBuiltin( Handle<SharedFunctionInfo> shared = NewSharedFunctionInfoForBuiltin(
literal->name(), Builtins::kCompileLazy, kind); literal->name(), Builtins::kCompileLazy, kind);
SharedFunctionInfo::InitFromFunctionLiteral(shared, literal, is_toplevel); SharedFunctionInfo::InitFromFunctionLiteral(shared, literal, is_toplevel);
SharedFunctionInfo::SetScript(shared, script, false); SharedFunctionInfo::SetScript(shared, script, literal->function_literal_id(),
false);
return shared; return shared;
} }
...@@ -3401,7 +3402,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( ...@@ -3401,7 +3402,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER); share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER); share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER); share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_function_literal_id(FunctionLiteral::kIdTypeInvalid);
#if V8_SFI_HAS_UNIQUE_ID #if V8_SFI_HAS_UNIQUE_ID
share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId()); share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
#endif #endif
......
...@@ -12750,9 +12750,8 @@ void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype, ...@@ -12750,9 +12750,8 @@ void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
map->set_prototype(*prototype, wb_mode); map->set_prototype(*prototype, wb_mode);
} }
Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
Handle<Object> CacheInitialJSArrayMaps( Handle<Map> initial_map) {
Handle<Context> native_context, Handle<Map> initial_map) {
// Replace all of the cached initial array maps in the native context with // Replace all of the cached initial array maps in the native context with
// the appropriate transitioned elements kind maps. // the appropriate transitioned elements kind maps.
Handle<Map> current_map = initial_map; Handle<Map> current_map = initial_map;
...@@ -12766,8 +12765,8 @@ Handle<Object> CacheInitialJSArrayMaps( ...@@ -12766,8 +12765,8 @@ Handle<Object> CacheInitialJSArrayMaps(
if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) { if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) {
new_map = handle(maybe_elements_transition); new_map = handle(maybe_elements_transition);
} else { } else {
new_map = Map::CopyAsElementsKind( new_map =
current_map, next_kind, INSERT_TRANSITION); Map::CopyAsElementsKind(current_map, next_kind, INSERT_TRANSITION);
} }
DCHECK_EQ(next_kind, new_map->elements_kind()); DCHECK_EQ(next_kind, new_map->elements_kind());
native_context->set(Context::ArrayMapIndex(next_kind), *new_map); native_context->set(Context::ArrayMapIndex(next_kind), *new_map);
...@@ -12869,7 +12868,6 @@ void JSFunction::SetPrototype(Handle<JSFunction> function, ...@@ -12869,7 +12868,6 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
SetInstancePrototype(isolate, function, construct_prototype); SetInstancePrototype(isolate, function, construct_prototype);
} }
void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map, void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
Handle<Object> prototype) { Handle<Object> prototype) {
if (map->prototype() != *prototype) Map::SetPrototype(map, prototype); if (map->prototype() != *prototype) Map::SetPrototype(map, prototype);
...@@ -13595,8 +13593,8 @@ SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() { ...@@ -13595,8 +13593,8 @@ SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() {
void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
Handle<Object> script_object, Handle<Object> script_object,
int function_literal_id,
bool reset_preparsed_scope_data) { bool reset_preparsed_scope_data) {
DCHECK_NE(shared->function_literal_id(), FunctionLiteral::kIdTypeInvalid);
if (shared->script() == *script_object) return; if (shared->script() == *script_object) return;
Isolate* isolate = shared->GetIsolate(); Isolate* isolate = shared->GetIsolate();
...@@ -13613,15 +13611,14 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, ...@@ -13613,15 +13611,14 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
Handle<WeakFixedArray> list = Handle<WeakFixedArray> list =
handle(script->shared_function_infos(), isolate); handle(script->shared_function_infos(), isolate);
#ifdef DEBUG #ifdef DEBUG
DCHECK_LT(shared->function_literal_id(), list->length()); DCHECK_LT(function_literal_id, list->length());
MaybeObject* maybe_object = list->Get(shared->function_literal_id()); MaybeObject* maybe_object = list->Get(function_literal_id);
HeapObject* heap_object; HeapObject* heap_object;
if (maybe_object->ToWeakHeapObject(&heap_object)) { if (maybe_object->ToWeakHeapObject(&heap_object)) {
DCHECK_EQ(heap_object, *shared); DCHECK_EQ(heap_object, *shared);
} }
#endif #endif
list->Set(shared->function_literal_id(), list->Set(function_literal_id, HeapObjectReference::Weak(*shared));
HeapObjectReference::Weak(*shared));
} else { } else {
Handle<Object> list = isolate->factory()->noscript_shared_function_infos(); Handle<Object> list = isolate->factory()->noscript_shared_function_infos();
...@@ -13647,13 +13644,13 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, ...@@ -13647,13 +13644,13 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
// Due to liveedit, it might happen that the old_script doesn't know // Due to liveedit, it might happen that the old_script doesn't know
// about the SharedFunctionInfo, so we have to guard against that. // about the SharedFunctionInfo, so we have to guard against that.
Handle<WeakFixedArray> infos(old_script->shared_function_infos(), isolate); Handle<WeakFixedArray> infos(old_script->shared_function_infos(), isolate);
if (shared->function_literal_id() < infos->length()) { if (function_literal_id < infos->length()) {
MaybeObject* raw = old_script->shared_function_infos()->Get( MaybeObject* raw =
shared->function_literal_id()); old_script->shared_function_infos()->Get(function_literal_id);
HeapObject* heap_object; HeapObject* heap_object;
if (raw->ToWeakHeapObject(&heap_object) && heap_object == *shared) { if (raw->ToWeakHeapObject(&heap_object) && heap_object == *shared) {
old_script->shared_function_infos()->Set( old_script->shared_function_infos()->Set(
shared->function_literal_id(), function_literal_id,
HeapObjectReference::Strong(isolate->heap()->undefined_value())); HeapObjectReference::Strong(isolate->heap()->undefined_value()));
} }
} }
...@@ -13794,6 +13791,29 @@ bool SharedFunctionInfo::IsInlineable() { ...@@ -13794,6 +13791,29 @@ bool SharedFunctionInfo::IsInlineable() {
int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); } int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); }
int SharedFunctionInfo::GetFunctionLiteralId(Isolate* isolate) const {
Object* script_obj = script();
if (!script_obj->IsScript()) return FunctionLiteral::kIdTypeInvalid;
WeakFixedArray* shared_info_list =
Script::cast(script_obj)->shared_function_infos();
SharedFunctionInfo::ScriptIterator iterator(
isolate, Handle<WeakFixedArray>(&shared_info_list));
// TODO(leszeks): If this turns out to be a performance bottleneck when
// initialising the ParseInfo for lazy compilation, we can probably change it
// to either a binary search using StartPosition, or cache it on the
// PreParseScopeData.
for (SharedFunctionInfo* shared = iterator.Next(); shared != nullptr;
shared = iterator.Next()) {
if (shared == this) {
return iterator.CurrentIndex();
}
}
return FunctionLiteral::kIdTypeInvalid;
}
void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type, void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
bool has_prototype_slot, bool has_prototype_slot,
int requested_embedder_fields, int requested_embedder_fields,
...@@ -13933,7 +13953,6 @@ void SharedFunctionInfo::InitFromFunctionLiteral( ...@@ -13933,7 +13953,6 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
// FunctionKind must have already been set. // FunctionKind must have already been set.
DCHECK(lit->kind() == shared_info->kind()); DCHECK(lit->kind() == shared_info->kind());
shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject()); shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
shared_info->set_function_literal_id(lit->function_literal_id());
DCHECK_IMPLIES(lit->requires_instance_fields_initializer(), DCHECK_IMPLIES(lit->requires_instance_fields_initializer(),
IsClassConstructor(lit->kind())); IsClassConstructor(lit->kind()));
shared_info->set_requires_instance_fields_initializer( shared_info->set_requires_instance_fields_initializer(
......
...@@ -43,7 +43,6 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type, ...@@ -43,7 +43,6 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type,
BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type, BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type,
is_toplevel, SharedFunctionInfo::IsTopLevelBit) is_toplevel, SharedFunctionInfo::IsTopLevelBit)
INT_ACCESSORS(SharedFunctionInfo, function_literal_id, kFunctionLiteralIdOffset)
#if V8_SFI_HAS_UNIQUE_ID #if V8_SFI_HAS_UNIQUE_ID
INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset) INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
#endif #endif
......
...@@ -83,7 +83,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -83,7 +83,7 @@ class SharedFunctionInfo : public HeapObject {
// function info is added to the list on the script. // function info is added to the list on the script.
V8_EXPORT_PRIVATE static void SetScript( V8_EXPORT_PRIVATE static void SetScript(
Handle<SharedFunctionInfo> shared, Handle<Object> script_object, Handle<SharedFunctionInfo> shared, Handle<Object> script_object,
bool reset_preparsed_scope_data = true); int function_literal_id, bool reset_preparsed_scope_data = true);
// Layout description of the optimized code map. // Layout description of the optimized code map.
static const int kEntriesStart = 0; static const int kEntriesStart = 0;
...@@ -149,11 +149,6 @@ class SharedFunctionInfo : public HeapObject { ...@@ -149,11 +149,6 @@ class SharedFunctionInfo : public HeapObject {
// function. The value is only reliable when the function has been compiled. // function. The value is only reliable when the function has been compiled.
DECL_INT_ACCESSORS(expected_nof_properties) DECL_INT_ACCESSORS(expected_nof_properties)
// [function_literal_id] - uniquely identifies the FunctionLiteral this
// SharedFunctionInfo represents within its script, or -1 if this
// SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
DECL_INT_ACCESSORS(function_literal_id)
#if V8_SFI_HAS_UNIQUE_ID #if V8_SFI_HAS_UNIQUE_ID
// [unique_id] - For --trace-maps purposes, an identifier that's persistent // [unique_id] - For --trace-maps purposes, an identifier that's persistent
// even if the GC moves this SharedFunctionInfo. // even if the GC moves this SharedFunctionInfo.
...@@ -222,6 +217,9 @@ class SharedFunctionInfo : public HeapObject { ...@@ -222,6 +217,9 @@ class SharedFunctionInfo : public HeapObject {
// [script]: Script from which the function originates. // [script]: Script from which the function originates.
DECL_ACCESSORS(script, Object) DECL_ACCESSORS(script, Object)
// Get the function literal id associated with this function, for parsing.
int GetFunctionLiteralId(Isolate* isolate) const;
// The function is subject to debugging if a debug info is attached. // The function is subject to debugging if a debug info is attached.
inline bool HasDebugInfo() const; inline bool HasDebugInfo() const;
DebugInfo* GetDebugInfo() const; DebugInfo* GetDebugInfo() const;
...@@ -438,6 +436,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -438,6 +436,7 @@ class SharedFunctionInfo : public HeapObject {
ScriptIterator(Isolate* isolate, ScriptIterator(Isolate* isolate,
Handle<WeakFixedArray> shared_function_infos); Handle<WeakFixedArray> shared_function_infos);
SharedFunctionInfo* Next(); SharedFunctionInfo* Next();
int CurrentIndex() const { return index_ - 1; }
// Reset the iterator to run on |script|. // Reset the iterator to run on |script|.
void Reset(Handle<Script> script); void Reset(Handle<Script> script);
...@@ -487,7 +486,6 @@ class SharedFunctionInfo : public HeapObject { ...@@ -487,7 +486,6 @@ class SharedFunctionInfo : public HeapObject {
V(kFunctionIdentifierOffset, kPointerSize) \ V(kFunctionIdentifierOffset, kPointerSize) \
V(kEndOfPointerFieldsOffset, 0) \ V(kEndOfPointerFieldsOffset, 0) \
/* Raw data fields. */ \ /* Raw data fields. */ \
V(kFunctionLiteralIdOffset, kInt32Size) \
V(kUniqueIdOffset, kUniqueIdFieldSize) \ V(kUniqueIdOffset, kUniqueIdFieldSize) \
V(kLengthOffset, kUInt16Size) \ V(kLengthOffset, kUInt16Size) \
V(kFormalParameterCountOffset, kUInt16Size) \ V(kFormalParameterCountOffset, kUInt16Size) \
......
...@@ -54,7 +54,7 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared) ...@@ -54,7 +54,7 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
set_function_flags(shared->flags()); set_function_flags(shared->flags());
set_start_position(shared->StartPosition()); set_start_position(shared->StartPosition());
set_end_position(shared->EndPosition()); set_end_position(shared->EndPosition());
function_literal_id_ = shared->function_literal_id(); function_literal_id_ = shared->GetFunctionLiteralId(isolate);
set_language_mode(shared->language_mode()); set_language_mode(shared->language_mode());
set_asm_wasm_broken(shared->is_asm_wasm_broken()); set_asm_wasm_broken(shared->is_asm_wasm_broken());
...@@ -105,42 +105,6 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<Script> script) ...@@ -105,42 +105,6 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<Script> script)
ParseInfo::~ParseInfo() {} ParseInfo::~ParseInfo() {}
// static
ParseInfo* ParseInfo::AllocateWithoutScript(Isolate* isolate,
Handle<SharedFunctionInfo> shared) {
ParseInfo* p = new ParseInfo(isolate->allocator());
p->InitFromIsolate(isolate);
p->set_toplevel(shared->is_toplevel());
p->set_allow_lazy_parsing(FLAG_lazy_inner_functions);
p->set_is_named_expression(shared->is_named_expression());
p->set_function_flags(shared->flags());
p->set_start_position(shared->StartPosition());
p->set_end_position(shared->EndPosition());
p->function_literal_id_ = shared->function_literal_id();
p->set_language_mode(shared->language_mode());
// BUG(5946): This function exists as a workaround until we can
// get rid of %SetCode in our native functions. The ParseInfo
// is explicitly set up for the case that:
// a) you have a native built-in,
// b) it's being run for the 2nd-Nth time in an isolate,
// c) we've already compiled bytecode and therefore don't need
// to parse.
// We tolerate a ParseInfo without a Script in this case.
p->set_native(true);
p->set_eval(false);
p->set_module(false);
DCHECK_NE(shared->kind(), FunctionKind::kModule);
Handle<HeapObject> scope_info(shared->GetOuterScopeInfo(), isolate);
if (!scope_info->IsTheHole(isolate) &&
Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
p->set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
}
return p;
}
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); } DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
bool ParseInfo::is_declaration() const { bool ParseInfo::is_declaration() const {
......
...@@ -45,9 +45,6 @@ class V8_EXPORT_PRIVATE ParseInfo { ...@@ -45,9 +45,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
void InitFromIsolate(Isolate* isolate); void InitFromIsolate(Isolate* isolate);
static ParseInfo* AllocateWithoutScript(Isolate* isolate,
Handle<SharedFunctionInfo> shared);
// Either returns the ast-value-factory associcated with this ParseInfo, or // Either returns the ast-value-factory associcated with this ParseInfo, or
// creates and returns a new factory if none exists. // creates and returns a new factory if none exists.
AstValueFactory* GetOrCreateAstValueFactory(); AstValueFactory* GetOrCreateAstValueFactory();
......
...@@ -119,16 +119,17 @@ RUNTIME_FUNCTION(Runtime_SetCode) { ...@@ -119,16 +119,17 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
bool was_native = target_shared->native(); bool was_native = target_shared->native();
target_shared->set_flags(source_shared->flags()); target_shared->set_flags(source_shared->flags());
target_shared->set_native(was_native); target_shared->set_native(was_native);
target_shared->set_function_literal_id(source_shared->function_literal_id());
target_shared->set_scope_info(source_shared->scope_info()); target_shared->set_scope_info(source_shared->scope_info());
Handle<Object> source_script(source_shared->script(), isolate); Handle<Object> source_script(source_shared->script(), isolate);
int function_literal_id = source_shared->GetFunctionLiteralId(isolate);
if (source_script->IsScript()) { if (source_script->IsScript()) {
SharedFunctionInfo::SetScript(source_shared, SharedFunctionInfo::SetScript(source_shared,
isolate->factory()->undefined_value()); isolate->factory()->undefined_value(),
function_literal_id);
} }
SharedFunctionInfo::SetScript(target_shared, source_script); SharedFunctionInfo::SetScript(target_shared, source_script,
function_literal_id);
// Set the code of the target function. // Set the code of the target function.
target->set_code(source_shared->GetCode()); target->set_code(source_shared->GetCode());
......
...@@ -103,7 +103,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) { ...@@ -103,7 +103,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
// Recreate the shared function infos array after changing the IDs of all // Recreate the shared function infos array after changing the IDs of all
// SharedFunctionInfos. // SharedFunctionInfos.
RUNTIME_FUNCTION(Runtime_LiveEditFixupScript) { RUNTIME_FUNCTION(Runtime_LiveEditResizeScriptFunctionArray) {
HandleScope scope(isolate); HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled()); CHECK(isolate->debug()->live_edit_enabled());
DCHECK_EQ(args.length(), 2); DCHECK_EQ(args.length(), 2);
...@@ -120,16 +120,19 @@ RUNTIME_FUNCTION(Runtime_LiveEditFixupScript) { ...@@ -120,16 +120,19 @@ RUNTIME_FUNCTION(Runtime_LiveEditFixupScript) {
RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) { RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
HandleScope scope(isolate); HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled()); CHECK(isolate->debug()->live_edit_enabled());
DCHECK_EQ(args.length(), 2); DCHECK_EQ(args.length(), 3);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
CONVERT_INT32_ARG_CHECKED(new_function_literal_id, 1); CONVERT_ARG_HANDLE_CHECKED(JSValue, script_value, 1);
CONVERT_INT32_ARG_CHECKED(new_function_literal_id, 2);
CHECK(SharedInfoWrapper::IsInstance(shared_info)); CHECK(SharedInfoWrapper::IsInstance(shared_info));
LiveEdit::FunctionSourceUpdated(shared_info, new_function_literal_id); CHECK(script_value->value()->IsScript());
Handle<Script> script(Script::cast(script_value->value()));
LiveEdit::FunctionSourceUpdated(shared_info, script, new_function_literal_id);
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
// Replaces code of SharedFunctionInfo with a new one. // Replaces code of SharedFunctionInfo with a new one.
RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) { RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
HandleScope scope(isolate); HandleScope scope(isolate);
...@@ -143,24 +146,39 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) { ...@@ -143,24 +146,39 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
// Connects SharedFunctionInfo to another script. // Connects SharedFunctionInfo to another script.
RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) { RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
HandleScope scope(isolate); HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled()); CHECK(isolate->debug()->live_edit_enabled());
DCHECK_EQ(2, args.length()); DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0); CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1); CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, function_literal_id_arg, 2);
if (function_object->IsJSValue()) { if (function_object->IsJSValue()) {
Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
if (script_object->IsJSValue()) { if (script_object->IsJSValue()) {
CHECK(JSValue::cast(*script_object)->value()->IsScript()); CHECK(JSValue::cast(*script_object)->value()->IsScript());
Script* script = Script::cast(JSValue::cast(*script_object)->value()); Script* script = Script::cast(JSValue::cast(*script_object)->value());
script_object = Handle<Object>(script, isolate); script_object = Handle<Object>(script, isolate);
} }
CHECK(function_wrapper->value()->IsSharedFunctionInfo()); CHECK(function_wrapper->value()->IsSharedFunctionInfo());
LiveEdit::SetFunctionScript(function_wrapper, script_object); int32_t function_literal_id = -1;
SharedFunctionInfo* shared =
SharedFunctionInfo::cast(function_wrapper->value());
if (function_literal_id_arg->IsNull(isolate)) {
if (shared->script()->IsScript()) {
function_literal_id = shared->GetFunctionLiteralId(isolate);
}
} else {
CHECK(function_literal_id_arg->IsNumber());
function_literal_id_arg->ToInt32(&function_literal_id);
}
LiveEdit::SetFunctionScript(function_wrapper, script_object,
function_literal_id);
} else { } else {
// Just ignore this. We may not have a SharedFunctionInfo for some functions // Just ignore this. We may not have a SharedFunctionInfo for some functions
// and we check it in this function. // and we check it in this function.
......
...@@ -291,9 +291,9 @@ namespace internal { ...@@ -291,9 +291,9 @@ namespace internal {
F(LiveEditCheckAndDropActivations, 3, 1) \ F(LiveEditCheckAndDropActivations, 3, 1) \
F(LiveEditCompareStrings, 2, 1) \ F(LiveEditCompareStrings, 2, 1) \
F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \ F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \
F(LiveEditFixupScript, 2, 1) \ F(LiveEditResizeScriptFunctionArray, 2, 1) \
F(LiveEditFunctionSetScript, 2, 1) \ F(LiveEditFunctionSetScript, 3, 1) \
F(LiveEditFunctionSourceUpdated, 2, 1) \ F(LiveEditFunctionSourceUpdated, 3, 1) \
F(LiveEditGatherCompileInfo, 2, 1) \ F(LiveEditGatherCompileInfo, 2, 1) \
F(LiveEditPatchFunctionPositions, 2, 1) \ F(LiveEditPatchFunctionPositions, 2, 1) \
F(LiveEditReplaceFunctionCode, 2, 1) \ F(LiveEditReplaceFunctionCode, 2, 1) \
......
...@@ -29,5 +29,7 @@ function listener(event, exec_state, event_data, data) { ...@@ -29,5 +29,7 @@ function listener(event, exec_state, event_data, data) {
Debug.setListener(listener); Debug.setListener(listener);
f(); f();
Debug.setListener(null); Debug.setListener(null);
assertNull(exception); if (exception != null) {
throw exception;
}
assertEquals(6, counter); assertEquals(6, counter);
...@@ -42,8 +42,7 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo( ...@@ -42,8 +42,7 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
// Make sure we have an outer scope info, even though it's empty // Make sure we have an outer scope info, even though it's empty
shared->set_raw_outer_scope_info_or_feedback_metadata( shared->set_raw_outer_scope_info_or_feedback_metadata(
ScopeInfo::Empty(isolate)); ScopeInfo::Empty(isolate));
shared->set_function_literal_id(1); SharedFunctionInfo::SetScript(shared, script, 1);
SharedFunctionInfo::SetScript(shared, script);
return scope.CloseAndEscape(shared); return scope.CloseAndEscape(shared);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment