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

Revert "[sfi] Remove SFI function literal id field"

This reverts commit ceb9c812.

Reason for revert: Tanks compile time

Original change's description:
> [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: Hannes Payer <hpayer@chromium.org>
> Reviewed-by: Toon Verwaest <verwaest@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#53523}

TBR=hpayer@chromium.org,leszeks@chromium.org,verwaest@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: chromium:818642
Bug: chromium:850417
Change-Id: If2fd21331b7062532c04004a51e705f7e9d0a151
Reviewed-on: https://chromium-review.googlesource.com/1090494Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53573}
parent 3db0672c
...@@ -620,9 +620,10 @@ Handle<JSFunction> Genesis::CreateEmptyFunction() { ...@@ -620,9 +620,10 @@ 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, 1); script);
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_->GetFunctionLiteralId(isolate)); parse_info_->set_function_literal_id(shared_->function_literal_id());
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,14 +863,12 @@ void LiveEdit::ReplaceFunctionCode( ...@@ -863,14 +863,12 @@ 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) {
...@@ -890,20 +888,17 @@ void LiveEdit::FixupScript(Handle<Script> script, int max_function_literal_id) { ...@@ -890,20 +888,17 @@ 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, iterator.CurrentIndex()); SharedFunctionInfo::SetScript(info, script);
} }
} }
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));
CHECK_IMPLIES(script_handle->IsScript(), function_literal_id >= 0); SharedFunctionInfo::SetScript(shared_info, script_handle);
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,13 +85,11 @@ class LiveEdit : AllStatic { ...@@ -85,13 +85,11 @@ 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,8 +207,6 @@ ...@@ -207,8 +207,6 @@
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.
...@@ -222,16 +220,17 @@ ...@@ -222,16 +220,17 @@
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, script, new_function_literal_id); 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. // 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;
...@@ -261,8 +260,7 @@ ...@@ -261,8 +260,7 @@
// 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);
} }
...@@ -361,12 +359,9 @@ ...@@ -361,12 +359,9 @@
// 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, null); %LiveEditFunctionSetScript(info.info, old_script);
}); });
report_array.push( { name: old_info_node.info.function_name } ); report_array.push( { name: old_info_node.info.function_name } );
......
...@@ -3323,8 +3323,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral( ...@@ -3323,8 +3323,7 @@ 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, literal->function_literal_id(), SharedFunctionInfo::SetScript(shared, script, false);
false);
return shared; return shared;
} }
...@@ -3412,6 +3411,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( ...@@ -3412,6 +3411,7 @@ 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,8 +12750,9 @@ void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype, ...@@ -12750,8 +12750,9 @@ 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<Map> initial_map) { Handle<Object> CacheInitialJSArrayMaps(
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;
...@@ -12765,8 +12766,8 @@ Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context, ...@@ -12765,8 +12766,8 @@ Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
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 = new_map = Map::CopyAsElementsKind(
Map::CopyAsElementsKind(current_map, next_kind, INSERT_TRANSITION); 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);
...@@ -12868,6 +12869,7 @@ void JSFunction::SetPrototype(Handle<JSFunction> function, ...@@ -12868,6 +12869,7 @@ 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);
...@@ -13593,8 +13595,8 @@ SharedFunctionInfo* SharedFunctionInfo::GlobalIterator::Next() { ...@@ -13593,8 +13595,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();
...@@ -13611,14 +13613,15 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, ...@@ -13611,14 +13613,15 @@ 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(function_literal_id, list->length()); DCHECK_LT(shared->function_literal_id(), list->length());
MaybeObject* maybe_object = list->Get(function_literal_id); MaybeObject* maybe_object = list->Get(shared->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(function_literal_id, HeapObjectReference::Weak(*shared)); list->Set(shared->function_literal_id(),
HeapObjectReference::Weak(*shared));
} else { } else {
Handle<Object> list = isolate->factory()->noscript_shared_function_infos(); Handle<Object> list = isolate->factory()->noscript_shared_function_infos();
...@@ -13644,13 +13647,13 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, ...@@ -13644,13 +13647,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 (function_literal_id < infos->length()) { if (shared->function_literal_id() < infos->length()) {
MaybeObject* raw = MaybeObject* raw = old_script->shared_function_infos()->Get(
old_script->shared_function_infos()->Get(function_literal_id); shared->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(
function_literal_id, shared->function_literal_id(),
HeapObjectReference::Strong(isolate->heap()->undefined_value())); HeapObjectReference::Strong(isolate->heap()->undefined_value()));
} }
} }
...@@ -13791,29 +13794,6 @@ bool SharedFunctionInfo::IsInlineable() { ...@@ -13791,29 +13794,6 @@ 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,
...@@ -13953,6 +13933,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral( ...@@ -13953,6 +13933,7 @@ 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,6 +43,7 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type, ...@@ -43,6 +43,7 @@ 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,
int function_literal_id, bool reset_preparsed_scope_data = true); 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,6 +149,11 @@ class SharedFunctionInfo : public HeapObject { ...@@ -149,6 +149,11 @@ 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.
...@@ -217,9 +222,6 @@ class SharedFunctionInfo : public HeapObject { ...@@ -217,9 +222,6 @@ 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;
...@@ -436,7 +438,6 @@ class SharedFunctionInfo : public HeapObject { ...@@ -436,7 +438,6 @@ 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);
...@@ -486,6 +487,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -486,6 +487,7 @@ 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->GetFunctionLiteralId(isolate); function_literal_id_ = shared->function_literal_id();
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,6 +105,42 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<Script> script) ...@@ -105,6 +105,42 @@ 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,6 +45,9 @@ class V8_EXPORT_PRIVATE ParseInfo { ...@@ -45,6 +45,9 @@ 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,17 +119,16 @@ RUNTIME_FUNCTION(Runtime_SetCode) { ...@@ -119,17 +119,16 @@ 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_LiveEditResizeScriptFunctionArray) { RUNTIME_FUNCTION(Runtime_LiveEditFixupScript) {
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,19 +120,16 @@ RUNTIME_FUNCTION(Runtime_LiveEditResizeScriptFunctionArray) { ...@@ -120,19 +120,16 @@ RUNTIME_FUNCTION(Runtime_LiveEditResizeScriptFunctionArray) {
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(), 3); DCHECK_EQ(args.length(), 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
CONVERT_ARG_HANDLE_CHECKED(JSValue, script_value, 1); CONVERT_INT32_ARG_CHECKED(new_function_literal_id, 1);
CONVERT_INT32_ARG_CHECKED(new_function_literal_id, 2);
CHECK(SharedInfoWrapper::IsInstance(shared_info)); CHECK(SharedInfoWrapper::IsInstance(shared_info));
CHECK(script_value->value()->IsScript()); LiveEdit::FunctionSourceUpdated(shared_info, new_function_literal_id);
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);
...@@ -146,39 +143,24 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) { ...@@ -146,39 +143,24 @@ 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(3, args.length()); DCHECK_EQ(2, 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());
int32_t function_literal_id = -1; LiveEdit::SetFunctionScript(function_wrapper, script_object);
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(LiveEditResizeScriptFunctionArray, 2, 1) \ F(LiveEditFixupScript, 2, 1) \
F(LiveEditFunctionSetScript, 3, 1) \ F(LiveEditFunctionSetScript, 2, 1) \
F(LiveEditFunctionSourceUpdated, 3, 1) \ F(LiveEditFunctionSourceUpdated, 2, 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,7 +29,5 @@ function listener(event, exec_state, event_data, data) { ...@@ -29,7 +29,5 @@ function listener(event, exec_state, event_data, data) {
Debug.setListener(listener); Debug.setListener(listener);
f(); f();
Debug.setListener(null); Debug.setListener(null);
if (exception != null) { assertNull(exception);
throw exception;
}
assertEquals(6, counter); assertEquals(6, counter);
...@@ -42,7 +42,8 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo( ...@@ -42,7 +42,8 @@ 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));
SharedFunctionInfo::SetScript(shared, script, 1); shared->set_function_literal_id(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