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:
bradnelson 2016-03-03 20:45:22 -08:00 committed by Commit bot
parent 38ce972085
commit 530cc16460
11 changed files with 69 additions and 31 deletions

View File

@ -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;

View File

@ -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) {
}

View File

@ -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);
}
}

View File

@ -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; }

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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 {

View File

@ -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();

View File

@ -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]],

View File

@ -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);