Handle stack frames differently inside and on the boundary of wasm.
Frames entering of inside wasm don't have a function or context argument. Adding distinct wasm frame and function types to express this. Fixes a GC issue on several embenchen wasm tests, reenabling them. BUG= https://code.google.com/p/v8/issues/detail?id=4203 TEST=mjsunit/wasm/embenchen R=titzer@chromium.org,aseemgarg@chromium.org,jfb@chromium.org,yangguo@chromium.org LOG=N Review URL: https://codereview.chromium.org/1764603003 Cr-Commit-Position: refs/heads/master@{#34476}
This commit is contained in:
parent
38ce972085
commit
530cc16460
@ -2233,8 +2233,7 @@ Handle<JSFunction> CompileJSToWasmWrapper(
|
||||
module->GetFunctionSignature(index)->parameter_count());
|
||||
CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
|
||||
&zone, false, params + 1, CallDescriptor::kNoFlags);
|
||||
// TODO(titzer): this is technically a WASM wrapper, not a wasm function.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION);
|
||||
Code::Flags flags = Code::ComputeFlags(Code::JS_TO_WASM_FUNCTION);
|
||||
bool debugging =
|
||||
#if DEBUG
|
||||
true;
|
||||
@ -2313,8 +2312,7 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
|
||||
// Schedule and compile to machine code.
|
||||
CallDescriptor* incoming =
|
||||
wasm::ModuleEnv::GetWasmCallDescriptor(&zone, sig);
|
||||
// TODO(titzer): this is technically a WASM wrapper, not a wasm function.
|
||||
Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION);
|
||||
Code::Flags flags = Code::ComputeFlags(Code::WASM_TO_JS_FUNCTION);
|
||||
bool debugging =
|
||||
#if DEBUG
|
||||
true;
|
||||
|
@ -242,6 +242,12 @@ inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
|
||||
inline WasmFrame::WasmFrame(StackFrameIteratorBase* iterator)
|
||||
: StandardFrame(iterator) {}
|
||||
|
||||
inline WasmToJsFrame::WasmToJsFrame(StackFrameIteratorBase* iterator)
|
||||
: WasmFrame(iterator) {}
|
||||
|
||||
inline JsToWasmFrame::JsToWasmFrame(StackFrameIteratorBase* iterator)
|
||||
: WasmFrame(iterator) {}
|
||||
|
||||
inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
|
||||
: StandardFrame(iterator) {
|
||||
}
|
||||
|
@ -459,6 +459,10 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
|
||||
return OPTIMIZED;
|
||||
case Code::WASM_FUNCTION:
|
||||
return WASM;
|
||||
case Code::WASM_TO_JS_FUNCTION:
|
||||
return WASM_TO_JS;
|
||||
case Code::JS_TO_WASM_FUNCTION:
|
||||
return JS_TO_WASM;
|
||||
case Code::BUILTIN:
|
||||
if (!marker->IsSmi()) {
|
||||
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
|
||||
@ -707,12 +711,14 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
|
||||
// Visit the return address in the callee and incoming arguments.
|
||||
IteratePc(v, pc_address(), constant_pool_address(), code);
|
||||
|
||||
// Visit the context in stub frame and JavaScript frame.
|
||||
// Visit the function in JavaScript frame.
|
||||
Object** fixed_base = &Memory::Object_at(
|
||||
fp() + StandardFrameConstants::kMarkerOffset);
|
||||
Object** fixed_limit = &Memory::Object_at(fp());
|
||||
v->VisitPointers(fixed_base, fixed_limit);
|
||||
if (!is_wasm() && !is_wasm_to_js()) {
|
||||
// Visit the context in stub frame and JavaScript frame.
|
||||
// Visit the function in JavaScript frame.
|
||||
Object** fixed_base =
|
||||
&Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset);
|
||||
Object** fixed_limit = &Memory::Object_at(fp());
|
||||
v->VisitPointers(fixed_base, fixed_limit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
26
src/frames.h
26
src/frames.h
@ -104,6 +104,8 @@ class StackHandler BASE_EMBEDDED {
|
||||
V(JAVA_SCRIPT, JavaScriptFrame) \
|
||||
V(OPTIMIZED, OptimizedFrame) \
|
||||
V(WASM, WasmFrame) \
|
||||
V(WASM_TO_JS, WasmToJsFrame) \
|
||||
V(JS_TO_WASM, JsToWasmFrame) \
|
||||
V(INTERPRETED, InterpretedFrame) \
|
||||
V(STUB, StubFrame) \
|
||||
V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
|
||||
@ -311,6 +313,8 @@ class StackFrame BASE_EMBEDDED {
|
||||
bool is_optimized() const { return type() == OPTIMIZED; }
|
||||
bool is_interpreted() const { return type() == INTERPRETED; }
|
||||
bool is_wasm() const { return type() == WASM; }
|
||||
bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
|
||||
bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
|
||||
bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
|
||||
bool is_internal() const { return type() == INTERNAL; }
|
||||
bool is_stub_failure_trampoline() const {
|
||||
@ -864,6 +868,28 @@ class WasmFrame : public StandardFrame {
|
||||
friend class StackFrameIteratorBase;
|
||||
};
|
||||
|
||||
class WasmToJsFrame : public WasmFrame {
|
||||
public:
|
||||
Type type() const override { return WASM_TO_JS; }
|
||||
|
||||
protected:
|
||||
inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
|
||||
|
||||
private:
|
||||
friend class StackFrameIteratorBase;
|
||||
};
|
||||
|
||||
class JsToWasmFrame : public WasmFrame {
|
||||
public:
|
||||
Type type() const override { return JS_TO_WASM; }
|
||||
|
||||
protected:
|
||||
inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
|
||||
|
||||
private:
|
||||
friend class StackFrameIteratorBase;
|
||||
};
|
||||
|
||||
class InternalFrame: public StandardFrame {
|
||||
public:
|
||||
Type type() const override { return INTERNAL; }
|
||||
|
10
src/log.cc
10
src/log.cc
@ -1576,7 +1576,15 @@ void Logger::LogCodeObject(Object* object) {
|
||||
tag = Logger::KEYED_STORE_IC_TAG;
|
||||
break;
|
||||
case AbstractCode::WASM_FUNCTION:
|
||||
description = "A wasm function";
|
||||
description = "A Wasm function";
|
||||
tag = Logger::STUB_TAG;
|
||||
break;
|
||||
case AbstractCode::JS_TO_WASM_FUNCTION:
|
||||
description = "A JavaScript to Wasm adapter";
|
||||
tag = Logger::STUB_TAG;
|
||||
break;
|
||||
case AbstractCode::WASM_TO_JS_FUNCTION:
|
||||
description = "A Wasm to JavaScript adapter";
|
||||
tag = Logger::STUB_TAG;
|
||||
break;
|
||||
}
|
||||
|
@ -4734,7 +4734,6 @@ Code::StubType Code::type() {
|
||||
return ExtractTypeFromFlags(flags());
|
||||
}
|
||||
|
||||
|
||||
// For initialization.
|
||||
void Code::set_raw_kind_specific_flags1(int value) {
|
||||
WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value);
|
||||
@ -5015,20 +5014,17 @@ Address Code::constant_pool() {
|
||||
return constant_pool;
|
||||
}
|
||||
|
||||
|
||||
Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state,
|
||||
ExtraICState extra_ic_state, StubType type,
|
||||
CacheHolderFlag holder) {
|
||||
// Compute the bit mask.
|
||||
unsigned int bits = KindField::encode(kind)
|
||||
| ICStateField::encode(ic_state)
|
||||
| TypeField::encode(type)
|
||||
| ExtraICStateField::encode(extra_ic_state)
|
||||
| CacheHolderField::encode(holder);
|
||||
unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) |
|
||||
TypeField::encode(type) |
|
||||
ExtraICStateField::encode(extra_ic_state) |
|
||||
CacheHolderField::encode(holder);
|
||||
return static_cast<Flags>(bits);
|
||||
}
|
||||
|
||||
|
||||
Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
|
||||
ExtraICState extra_ic_state,
|
||||
CacheHolderFlag holder,
|
||||
@ -5062,7 +5058,6 @@ Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
|
||||
return TypeField::decode(flags);
|
||||
}
|
||||
|
||||
|
||||
CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
|
||||
return CacheHolderField::decode(flags);
|
||||
}
|
||||
|
@ -4872,7 +4872,9 @@ class Code: public HeapObject {
|
||||
V(HANDLER) \
|
||||
V(BUILTIN) \
|
||||
V(REGEXP) \
|
||||
V(WASM_FUNCTION)
|
||||
V(WASM_FUNCTION) \
|
||||
V(WASM_TO_JS_FUNCTION) \
|
||||
V(JS_TO_WASM_FUNCTION)
|
||||
|
||||
#define IC_KIND_LIST(V) \
|
||||
V(LOAD_IC) \
|
||||
@ -5323,8 +5325,9 @@ class Code: public HeapObject {
|
||||
class TypeField : public BitField<StubType, 3, 1> {};
|
||||
class CacheHolderField : public BitField<CacheHolderFlag, 4, 2> {};
|
||||
class KindField : public BitField<Kind, 6, 5> {};
|
||||
class ExtraICStateField: public BitField<ExtraICState, 11,
|
||||
PlatformSmiTagging::kSmiValueSize - 11 + 1> {}; // NOLINT
|
||||
class ExtraICStateField
|
||||
: public BitField<ExtraICState, 11, PlatformSmiTagging::kSmiValueSize -
|
||||
11 + 1> {}; // NOLINT
|
||||
|
||||
// KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
|
||||
static const int kStackSlotsFirstBit = 0;
|
||||
|
@ -58,7 +58,7 @@ struct TickSample {
|
||||
unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
|
||||
bool has_external_callback : 1;
|
||||
bool update_stats : 1; // Whether the sample should update aggregated stats.
|
||||
StackFrame::Type top_frame_type : 4;
|
||||
StackFrame::Type top_frame_type : 5;
|
||||
};
|
||||
|
||||
class Sampler {
|
||||
|
@ -84,6 +84,8 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
|
||||
SerializeGeneric(code_object, how_to_code, where_to_point);
|
||||
return;
|
||||
case Code::WASM_FUNCTION:
|
||||
case Code::WASM_TO_JS_FUNCTION:
|
||||
case Code::JS_TO_WASM_FUNCTION:
|
||||
UNREACHABLE();
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
@ -318,10 +318,6 @@
|
||||
'wasm/embenchen/copy': [FAIL], # wrong answer
|
||||
'wasm/embenchen/box2d': [SKIP], # hang
|
||||
'wasm/embenchen/lua_binarytrees': [SKIP], # fails decode
|
||||
'wasm/embenchen/primes': [SKIP], # crashes under gc-stress
|
||||
'wasm/embenchen/fannkuch': [SKIP], # crash (seems to be gc issue)
|
||||
'wasm/embenchen/fasta': [SKIP], # flaky crash
|
||||
'wasm/embenchen/zlib': [SKIP], # flaky crash
|
||||
|
||||
# case-insensitive unicode regexp relies on case mapping provided by ICU.
|
||||
'harmony/unicode-regexp-ignore-case': [PASS, ['no_i18n == True', FAIL]],
|
||||
|
@ -63,10 +63,8 @@ var expected = "Error\n" +
|
||||
// The line numbers below will change as this test gains / loses lines..
|
||||
" at STACK (stack.js:54:11)\n" + // --
|
||||
" at <WASM> (<anonymous>)\n" + // --
|
||||
" at <WASM> (<anonymous>)\n" + // --
|
||||
" at <WASM> (<anonymous>)\n" + // --
|
||||
" at testStack (stack.js:43:10)\n" +
|
||||
// TODO(jfb) Add WebAssembly stack here.
|
||||
" at stack.js:72:1";
|
||||
" at stack.js:70:1";
|
||||
|
||||
testStack(STACK, check_STACK);
|
||||
|
Loading…
Reference in New Issue
Block a user