Skip to content

Commit

Permalink
[sfi] Replace start/end position with UncompiledData
Browse files Browse the repository at this point in the history
Add new types for function data for SharedFunctionInfo, for uncompiled
functions. UncompiledData holds start/end positions, allowing us to
remove these fields from SFI. Uncompiled functions with pre-parsed
scope data now hold an UncompiledDataWithScope that has a pointer to
PreParsedScopeData -- this allows us to also remove the start/end pos
from PreParsedScopeData.

Bug: chromium:818642
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I56f3c4e62cbf38929babac734a332709f12a8202
Reviewed-on: https://chromium-review.googlesource.com/1126381
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54319}
  • Loading branch information
LeszekSwirski authored and Commit Bot committed Jul 9, 2018
1 parent 43744b9 commit 39e2d97
Show file tree
Hide file tree
Showing 30 changed files with 808 additions and 454 deletions.
44 changes: 32 additions & 12 deletions src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,33 @@ StartupData SnapshotCreator::CreateBlob(

isolate->heap()->read_only_space()->ClearStringPaddingIfNeeded();

if (function_code_handling == FunctionCodeHandling::kClear) {
// Clear out re-compilable data from all shared function infos. Any
// JSFunctions using these SFIs will have their code pointers reset by the
// partial serializer.
//
// We have to iterate the heap and collect handles to each clearable SFI,
// before we disable allocation, since we have to allocate UncompiledDatas
// to be able to recompile them.
i::HandleScope scope(isolate);
std::vector<i::Handle<i::SharedFunctionInfo>> sfis_to_clear;

i::HeapIterator heap_iterator(isolate->heap());
while (i::HeapObject* current_obj = heap_iterator.next()) {
if (current_obj->IsSharedFunctionInfo()) {
i::SharedFunctionInfo* shared =
i::SharedFunctionInfo::cast(current_obj);
if (shared->CanDiscardCompiled()) {
sfis_to_clear.emplace_back(shared, isolate);
}
}
}
i::AllowHeapAllocation allocate_for_discard;
for (i::Handle<i::SharedFunctionInfo> shared : sfis_to_clear) {
i::SharedFunctionInfo::DiscardCompiled(isolate, shared);
}
}

i::DisallowHeapAllocation no_gc_from_here_on;

int num_contexts = num_additional_contexts + 1;
Expand Down Expand Up @@ -778,19 +805,12 @@ StartupData SnapshotCreator::CreateBlob(
i::ReadOnlyRoots(isolate).undefined_value());
fun->set_code(isolate->builtins()->builtin(i::Builtins::kCompileLazy));
}
}

// Clear out re-compilable data from all shared function infos. Any
// JSFunctions using these SFIs will have their code pointers reset by the
// partial serializer.
if (current_obj->IsSharedFunctionInfo() &&
function_code_handling == FunctionCodeHandling::kClear) {
i::SharedFunctionInfo* shared = i::SharedFunctionInfo::cast(current_obj);
if (shared->CanFlushCompiled()) {
shared->FlushCompiled();
if (function_code_handling == FunctionCodeHandling::kClear) {
DCHECK(fun->shared()->HasWasmExportedFunctionData() ||
fun->shared()->HasBuiltinId() ||
fun->shared()->IsApiFunction() ||
fun->shared()->HasUncompiledDataWithoutPreParsedScope());
}
DCHECK(shared->HasWasmExportedFunctionData() || shared->HasBuiltinId() ||
shared->IsApiFunction());
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/bootstrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,6 @@ Handle<JSFunction> Genesis::CreateEmptyFunction() {
script->set_type(Script::TYPE_NATIVE);
Handle<WeakFixedArray> infos = factory()->NewWeakFixedArray(2);
script->set_shared_function_infos(*infos);
// TODO(cbruni): fix position information here.
empty_function->shared()->set_raw_start_position(0);
empty_function->shared()->set_raw_end_position(source->length());
empty_function->shared()->set_scope_info(*scope_info);
empty_function->shared()->set_function_literal_id(1);
empty_function->shared()->DontAdaptArguments();
Expand Down
27 changes: 18 additions & 9 deletions src/code-stub-assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11983,18 +11983,24 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
TNode<Int32T> data_type = LoadInstanceType(CAST(sfi_data));

int32_t case_values[] = {BYTECODE_ARRAY_TYPE,
WASM_EXPORTED_FUNCTION_DATA_TYPE, FIXED_ARRAY_TYPE,
TUPLE2_TYPE, FUNCTION_TEMPLATE_INFO_TYPE};
WASM_EXPORTED_FUNCTION_DATA_TYPE,
FIXED_ARRAY_TYPE,
UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE,
UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE,
FUNCTION_TEMPLATE_INFO_TYPE};
Label check_is_bytecode_array(this);
Label check_is_exported_function_data(this);
Label check_is_fixed_array(this);
Label check_is_pre_parsed_scope_data(this);
Label check_is_uncompiled_data_without_pre_parsed_scope(this);
Label check_is_uncompiled_data_with_pre_parsed_scope(this);
Label check_is_function_template_info(this);
Label check_is_interpreter_data(this);
Label* case_labels[] = {
&check_is_bytecode_array, &check_is_exported_function_data,
&check_is_fixed_array, &check_is_pre_parsed_scope_data,
&check_is_function_template_info};
Label* case_labels[] = {&check_is_bytecode_array,
&check_is_exported_function_data,
&check_is_fixed_array,
&check_is_uncompiled_data_without_pre_parsed_scope,
&check_is_uncompiled_data_with_pre_parsed_scope,
&check_is_function_template_info};
STATIC_ASSERT(arraysize(case_values) == arraysize(case_labels));
Switch(data_type, &check_is_interpreter_data, case_values, case_labels,
arraysize(case_labels));
Expand All @@ -12017,8 +12023,11 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
sfi_code = HeapConstant(BUILTIN_CODE(isolate(), InstantiateAsmJs));
Goto(&done);

// IsPreParsedScopeData: Compile lazy
BIND(&check_is_pre_parsed_scope_data);
// IsUncompiledDataWithPreParsedScope | IsUncompiledDataWithoutPreParsedScope:
// Compile lazy
BIND(&check_is_uncompiled_data_with_pre_parsed_scope);
Goto(&check_is_uncompiled_data_without_pre_parsed_scope);
BIND(&check_is_uncompiled_data_without_pre_parsed_scope);
DCHECK(!Builtins::IsLazy(Builtins::kCompileLazy));
sfi_code = HeapConstant(BUILTIN_CODE(isolate(), CompileLazy));
Goto(if_compile_lazy ? if_compile_lazy : &done);
Expand Down
6 changes: 6 additions & 0 deletions src/code-stub-assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(Tuple3Map, tuple3_map, Tuple3Map) \
V(ArrayBoilerplateDescriptionMap, array_boilerplate_description_map, \
ArrayBoilerplateDescriptionMap) \
V(UncompiledDataWithoutPreParsedScopeMap, \
uncompiled_data_without_pre_parsed_scope_map, \
UncompiledDataWithoutPreParsedScopeMap) \
V(UncompiledDataWithPreParsedScopeMap, \
uncompiled_data_with_pre_parsed_scope_map, \
UncompiledDataWithPreParsedScopeMap) \
V(UndefinedValue, undefined_value, Undefined) \
V(WeakCellMap, weak_cell_map, WeakCellMap) \
V(WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArrayMap)
Expand Down
13 changes: 5 additions & 8 deletions src/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1087,14 +1087,11 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
}

if (FLAG_preparser_scope_analysis) {
if (shared_info->HasPreParsedScopeData()) {
Handle<PreParsedScopeData> data(
PreParsedScopeData::cast(shared_info->preparsed_scope_data()),
isolate);
parse_info.consumed_preparsed_scope_data()->SetData(isolate, data);
// After we've compiled the function, we don't need data about its
// skippable functions any more.
shared_info->ClearPreParsedScopeData();
if (shared_info->HasUncompiledDataWithPreParsedScope()) {
parse_info.consumed_preparsed_scope_data()->SetData(
isolate, handle(shared_info->uncompiled_data_with_pre_parsed_scope()
->pre_parsed_scope_data(),
isolate));
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/compiler/types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
case MODULE_TYPE:
case MODULE_INFO_ENTRY_TYPE:
case CELL_TYPE:
case UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE:
case UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE:
return kOtherInternal;

// Remaining instance types are unsupported for now. If any of them do
Expand Down
14 changes: 6 additions & 8 deletions src/debug/liveedit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -974,13 +974,9 @@ void UpdatePositions(Isolate* isolate, Handle<SharedFunctionInfo> sfi,
int new_end_position = LiveEdit::TranslatePosition(diffs, sfi->EndPosition());
int new_function_token_position =
LiveEdit::TranslatePosition(diffs, sfi->function_token_position());

sfi->set_raw_start_position(new_start_position);
sfi->set_raw_end_position(new_end_position);
if (sfi->scope_info()->HasPositionInfo()) {
sfi->scope_info()->SetPositionInfo(new_start_position, new_end_position);
}
sfi->SetFunctionTokenPosition(new_function_token_position);
sfi->SetPosition(new_start_position, new_end_position);
sfi->SetFunctionTokenPosition(new_function_token_position,
new_start_position);
if (sfi->HasBytecodeArray()) {
TranslateSourcePositionTable(handle(sfi->GetBytecodeArray(), isolate),
diffs);
Expand Down Expand Up @@ -1066,7 +1062,9 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
new_script_sfis->Set(mapping.second->function_literal_id(),
HeapObjectReference::Weak(*sfi));

if (sfi->HasPreParsedScopeData()) sfi->ClearPreParsedScopeData();
if (sfi->HasUncompiledDataWithPreParsedScope()) {
sfi->ClearPreParsedScopeData();
}

for (auto& js_function : data->js_functions) {
js_function->set_feedback_cell(*isolate->factory()->many_closures_cell());
Expand Down
28 changes: 26 additions & 2 deletions src/heap/factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2495,6 +2495,32 @@ Handle<PreParsedScopeData> Factory::NewPreParsedScopeData() {
return result;
}

Handle<UncompiledDataWithoutPreParsedScope>
Factory::NewUncompiledDataWithoutPreParsedScope(int32_t start_position,
int32_t end_position) {
Handle<UncompiledDataWithoutPreParsedScope> result(
UncompiledDataWithoutPreParsedScope::cast(
New(uncompiled_data_without_pre_parsed_scope_map(), TENURED)),
isolate());
result->set_start_position(start_position);
result->set_end_position(end_position);
return result;
}

Handle<UncompiledDataWithPreParsedScope>
Factory::NewUncompiledDataWithPreParsedScope(
int32_t start_position, int32_t end_position,
Handle<PreParsedScopeData> pre_parsed_scope_data) {
Handle<UncompiledDataWithPreParsedScope> result(
UncompiledDataWithPreParsedScope::cast(
New(uncompiled_data_with_pre_parsed_scope_map(), TENURED)),
isolate());
result->set_start_position(start_position);
result->set_end_position(end_position);
result->set_pre_parsed_scope_data(*pre_parsed_scope_data);
return result;
}

Handle<JSObject> Factory::NewExternal(void* value) {
Handle<Foreign> foreign = NewForeign(reinterpret_cast<Address>(value));
Handle<JSObject> external = NewJSObjectFromMap(external_map());
Expand Down Expand Up @@ -3470,8 +3496,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_length(0);
share->set_internal_formal_parameter_count(0);
share->set_expected_nof_properties(0);
share->set_raw_start_position_and_type(0);
share->set_raw_end_position(0);
share->set_raw_function_token_offset(0);
// All flags default to false or 0.
share->set_flags(0);
Expand Down
9 changes: 9 additions & 0 deletions src/heap/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class RegExpMatchInfo;
class ScriptContextTable;
class StoreHandler;
class TemplateObjectDescription;
class UncompiledDataWithoutPreParsedScope;
class UncompiledDataWithPreParsedScope;
class WasmExportedFunctionData;
struct SourceRange;
template <typename T>
Expand Down Expand Up @@ -717,6 +719,13 @@ class V8_EXPORT_PRIVATE Factory {

Handle<PreParsedScopeData> NewPreParsedScopeData();

Handle<UncompiledDataWithoutPreParsedScope>
NewUncompiledDataWithoutPreParsedScope(int32_t start_position,
int32_t end_position);

Handle<UncompiledDataWithPreParsedScope> NewUncompiledDataWithPreParsedScope(
int32_t start_position, int32_t end_position, Handle<PreParsedScopeData>);

// Create an External object for V8's external API.
Handle<JSObject> NewExternal(void* value);

Expand Down
Loading

0 comments on commit 39e2d97

Please sign in to comment.