[compiler] Improve contract for Compiler::CompileDebugCode.
This changes the contract for the aforementioned API function to be more permissive and allow callers to call it with less restrictions. The new contract is: a) For so far un-compiled functions, the compiler is free to choose the backend according to other decision criteria. Debug code can hence be provided by either Ignition or FullCodegen. b) For compiled functions, the compiler will provide debug code within the same tier as existing code. For Ignition the generated code will be equivalent to the old one. For FullCodegen the code will contain debug information and debug break slots. Concretely this fixes an issue where generator or async functions might have been compiled with an unexpected backend, due to the fact that the API method in question was always providing FullCodegen code. R=yangguo@chromium.org Review-Url: https://codereview.chromium.org/2044063002 Cr-Commit-Position: refs/heads/master@{#36808}
This commit is contained in:
parent
1e3a38d962
commit
80b98da2cd
@ -433,7 +433,15 @@ void EnsureFeedbackMetadata(CompilationInfo* info) {
|
||||
}
|
||||
|
||||
bool UseIgnition(CompilationInfo* info) {
|
||||
if (info->is_debug()) return false;
|
||||
DCHECK(info->has_shared_info());
|
||||
|
||||
// When requesting debug code as a replacement for existing code, we provide
|
||||
// the same kind as the existing code (to prevent implicit tier-change).
|
||||
if (info->is_debug() && info->shared_info()->is_compiled()) {
|
||||
return info->shared_info()->HasBytecodeArray();
|
||||
}
|
||||
|
||||
// For generator or async functions we might avoid Ignition wholesale.
|
||||
if (info->shared_info()->is_resumable() && !FLAG_ignition_generators) {
|
||||
return false;
|
||||
}
|
||||
@ -509,6 +517,12 @@ void InstallSharedScopeInfo(CompilationInfo* info,
|
||||
|
||||
void InstallSharedCompilationResult(CompilationInfo* info,
|
||||
Handle<SharedFunctionInfo> shared) {
|
||||
// TODO(mstarzinger): Compiling for debug code might be used to reveal inner
|
||||
// functions via {FindSharedFunctionInfoInScript}, in which case we end up
|
||||
// regenerating existing bytecode. Fix this!
|
||||
if (info->is_debug() && info->has_bytecode_array()) {
|
||||
shared->ClearBytecodeArray();
|
||||
}
|
||||
// Assert that we are not overwriting (possibly patched) debug code.
|
||||
DCHECK(!shared->HasDebugInfo());
|
||||
DCHECK(!info->code().is_null());
|
||||
|
@ -621,11 +621,9 @@ void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
|
||||
this->SetSmiValueField(kParentIndexOffset_, parent_index);
|
||||
}
|
||||
|
||||
|
||||
void FunctionInfoWrapper::SetFunctionCode(Handle<Code> function_code,
|
||||
void FunctionInfoWrapper::SetFunctionCode(Handle<AbstractCode> function_code,
|
||||
Handle<HeapObject> code_scope_info) {
|
||||
// CompileForLiveEdit must deliver full-codegen code.
|
||||
DCHECK(function_code->kind() == Code::FUNCTION);
|
||||
Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
|
||||
this->SetField(kCodeOffset_, code_wrapper);
|
||||
|
||||
@ -640,13 +638,12 @@ void FunctionInfoWrapper::SetSharedFunctionInfo(
|
||||
this->SetField(kSharedFunctionInfoOffset_, info_holder);
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
|
||||
Handle<AbstractCode> FunctionInfoWrapper::GetFunctionCode() {
|
||||
Handle<Object> element = this->GetField(kCodeOffset_);
|
||||
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
|
||||
Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
|
||||
CHECK(raw_result->IsCode());
|
||||
return Handle<Code>::cast(raw_result);
|
||||
CHECK(raw_result->IsAbstractCode());
|
||||
return Handle<AbstractCode>::cast(raw_result);
|
||||
}
|
||||
|
||||
MaybeHandle<TypeFeedbackMetadata> FunctionInfoWrapper::GetFeedbackMetadata() {
|
||||
@ -1012,16 +1009,17 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
bool feedback_metadata_changed = false;
|
||||
|
||||
if (shared_info->is_compiled()) {
|
||||
Handle<Code> new_code = compile_info_wrapper.GetFunctionCode();
|
||||
Handle<Code> old_code(shared_info->code());
|
||||
Handle<AbstractCode> new_code = compile_info_wrapper.GetFunctionCode();
|
||||
if (shared_info->HasBytecodeArray()) {
|
||||
// The old code is interpreted. If we clear the bytecode array, the
|
||||
// interpreter entry trampoline will self-heal and go to compiled code.
|
||||
DCHECK(new_code->IsBytecodeArray());
|
||||
// The old code is interpreted, the new code must be interpreted as well.
|
||||
shared_info->ClearBytecodeArray();
|
||||
shared_info->ReplaceCode(*new_code);
|
||||
shared_info->set_bytecode_array(BytecodeArray::cast(*new_code));
|
||||
} else {
|
||||
Handle<Code> old_code(shared_info->code());
|
||||
DCHECK(old_code->kind() == Code::FUNCTION);
|
||||
ReplaceCodeObject(old_code, new_code);
|
||||
DCHECK(new_code->kind() == AbstractCode::FUNCTION);
|
||||
ReplaceCodeObject(old_code, Handle<Code>::cast(new_code));
|
||||
}
|
||||
if (shared_info->HasDebugInfo()) {
|
||||
// Existing break points will be re-applied. Reset the debug info here.
|
||||
@ -2002,7 +2000,7 @@ void LiveEditFunctionTracker::FunctionDone(Handle<SharedFunctionInfo> shared,
|
||||
FunctionInfoWrapper info = FunctionInfoWrapper::cast(
|
||||
*JSReceiver::GetElement(isolate_, result_, current_parent_index_)
|
||||
.ToHandleChecked());
|
||||
info.SetFunctionCode(Handle<Code>(shared->code()),
|
||||
info.SetFunctionCode(Handle<AbstractCode>(shared->abstract_code()),
|
||||
Handle<HeapObject>(shared->scope_info()));
|
||||
info.SetSharedFunctionInfo(shared);
|
||||
|
||||
|
@ -292,7 +292,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
int end_position, int param_num, int literal_count,
|
||||
int parent_index);
|
||||
|
||||
void SetFunctionCode(Handle<Code> function_code,
|
||||
void SetFunctionCode(Handle<AbstractCode> function_code,
|
||||
Handle<HeapObject> code_scope_info);
|
||||
|
||||
void SetFunctionScopeInfo(Handle<Object> scope_info_array) {
|
||||
@ -309,7 +309,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
return this->GetSmiValueField(kParentIndexOffset_);
|
||||
}
|
||||
|
||||
Handle<Code> GetFunctionCode();
|
||||
Handle<AbstractCode> GetFunctionCode();
|
||||
|
||||
MaybeHandle<TypeFeedbackMetadata> GetFeedbackMetadata();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user