[wasm][gc] Fix NativeModule::GetCode for nonexisting code

{NativeModule::GetCode} can actually return {nullptr} if no code was
compiled yet for a function, e.g. in asm.js where we use lazy
compilation. In that case, we must not try to increment the ref count
on the nonexisting code object.

We had a few errors recently that were hard to reproduce because we do
not have a flag to enable code logging. Clusterfuzz managed to
accomplish this by passing --trace-ic.
In order to test bugs in code logging properly, this CL introduces a
new runtime function called "EnableCodeLoggingForTesting". It registers
a noop {CodeEventListener} and enables code logging in the wasm engine.
We should whitelist this flag in ClusterFuzz to potentially flush out
more bugs.

R=mstarzinger@chromium.org
CC=frgossen@chromium.org

Bug: v8:8217, chromium:961129, chromium:961245, chromium:961128
Change-Id: I2f97c109db70b41531d58580b71f6781beeb8dcb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1602700
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61404}
This commit is contained in:
Clemens Hammacher 2019-05-10 11:05:06 +02:00 committed by Commit Bot
parent fc95e35baa
commit 0975c55409
4 changed files with 58 additions and 3 deletions

View File

@ -1284,5 +1284,41 @@ RUNTIME_FUNCTION(Runtime_StaticAssert) {
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_EnableCodeLoggingForTesting) {
// The {NoopListener} currently does nothing on any callback, but reports
// {true} on {is_listening_to_code_events()}. Feel free to add assertions to
// any method to further test the code logging callbacks.
class NoopListener final : public CodeEventListener {
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
const char* comment) final {}
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
Name name) final {}
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
SharedFunctionInfo shared, Name source) final {}
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
SharedFunctionInfo shared, Name source, int line,
int column) final {}
void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
wasm::WasmName name) final {}
void CallbackEvent(Name name, Address entry_point) final {}
void GetterCallbackEvent(Name name, Address entry_point) final {}
void SetterCallbackEvent(Name name, Address entry_point) final {}
void RegExpCodeCreateEvent(AbstractCode code, String source) final {}
void CodeMoveEvent(AbstractCode from, AbstractCode to) final {}
void SharedFunctionInfoMoveEvent(Address from, Address to) final {}
void CodeMovingGCEvent() final {}
void CodeDisableOptEvent(AbstractCode code,
SharedFunctionInfo shared) final {}
void CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) final {}
bool is_listening_to_code_events() final { return true; }
};
static base::LeakyObject<NoopListener> noop_listener;
isolate->wasm_engine()->EnableCodeLogging(isolate);
isolate->code_event_dispatcher()->AddListener(noop_listener.get());
return ReadOnlyRoots(isolate).undefined_value();
}
} // namespace internal
} // namespace v8

View File

@ -519,7 +519,8 @@ namespace internal {
F(WasmNumInterpretedCalls, 1, 1) \
F(WasmTraceMemory, 1, 1) \
F(SetWasmThreadsEnabled, 1, 1) \
F(StaticAssert, 1, 1)
F(StaticAssert, 1, 1) \
F(EnableCodeLoggingForTesting, 0, 1)
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F, I) \
F(ArrayBufferDetach, 1, 1) \

View File

@ -149,7 +149,7 @@ bool WasmCode::ShouldBeLogged(Isolate* isolate) {
// The return value is cached in {WasmEngine::IsolateData::log_codes}. Ensure
// to call {WasmEngine::EnableCodeLogging} if this return value would change
// for any isolate. Otherwise we might lose code events.
return isolate->logger()->is_listening_to_code_events() ||
return isolate->code_event_dispatcher()->IsListeningToCodeEvents() ||
isolate->is_profiling();
}
@ -832,7 +832,7 @@ WasmCode* NativeModule::GetCode(uint32_t index) const {
DCHECK_LT(index, num_functions());
DCHECK_LE(module_->num_imported_functions, index);
WasmCode* code = code_table_[index - module_->num_imported_functions];
WasmCodeRefScope::AddRef(code);
if (code) WasmCodeRefScope::AddRef(code);
return code;
}

View File

@ -0,0 +1,18 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
%EnableCodeLoggingForTesting();
function module() {
"use asm";
function f() {
var i = 4;
return i | 0;
}
return {f: f};
}
module().f();