Commit 86fa01c7 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

Add code flag for non-tagged parameters

The WasmCompileLazy builtin creates an internal frame, thus the garbage
collector will visit all pointers in the stack frame.
However, we will call this builtin from compiled wasm code, and it
receives raw (untagged) arguments. This is because this builtin is
later exchanged by compiled wasm code, so the ABI needs to be
compatible.

This CL introduces the has_tagged_params code flag, which is true by
default and false for each WASM_FUNCTION, JS_TO_WASM_FUNCTION and
the WasmCompileLazy builtin.
The gargabe collector just ignores the parameters for each frame
whose code object has this flag set to false. For internal frames,
all pointers in the whole stack frame are ignored if the flag is set.

R=titzer@chromium.org, mstarzinger@chromium.org
BUG=v8:5991

Change-Id: I12a15157db344725bcc280e2041fd5bcad2ba700
Reviewed-on: https://chromium-review.googlesource.com/451400
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43884}
parent 215a2fa4
......@@ -181,6 +181,11 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
BUILTIN_EXCEPTION_CAUGHT_PREDICTION_LIST(SET_EXCEPTION_CAUGHT_PREDICTION)
#undef SET_EXCEPTION_CAUGHT_PREDICTION
#define SET_CODE_NON_TAGGED_PARAMS(Name) \
Code::cast(builtins_[k##Name])->set_has_tagged_params(false);
BUILTINS_WITH_UNTAGGED_PARAMS(SET_CODE_NON_TAGGED_PARAMS)
#undef SET_CODE_NON_TAGGED_PARAMS
}
// Mark as initialized.
......
......@@ -908,6 +908,9 @@ class Isolate;
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
IGNORE_BUILTIN, IGNORE_BUILTIN, V)
// TODO(clemensh): Add WasmCompileLazy once that CL lands.
#define BUILTINS_WITH_UNTAGGED_PARAMS(V)
// Forward declarations.
class ObjectVisitor;
enum class InterpreterPushArgsMode : unsigned;
......
......@@ -1692,6 +1692,7 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
code->set_raw_kind_specific_flags1(0);
code->set_raw_kind_specific_flags2(0);
code->set_is_crankshafted(crankshafted);
code->set_has_tagged_params(true);
code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER);
code->set_raw_type_feedback_info(Smi::kZero);
code->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER);
......@@ -1702,8 +1703,16 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
code->set_builtin_index(-1);
code->set_trap_handler_index(Smi::FromInt(-1));
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
code->set_marked_for_deoptimization(false);
switch (code->kind()) {
case Code::OPTIMIZED_FUNCTION:
code->set_marked_for_deoptimization(false);
break;
case Code::JS_TO_WASM_FUNCTION:
case Code::WASM_FUNCTION:
code->set_has_tagged_params(false);
break;
default:
break;
}
if (is_debug) {
......
......@@ -413,13 +413,12 @@ void StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address,
unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
Object* code = holder;
v->VisitPointer(&code);
if (code != holder) {
holder = reinterpret_cast<Code*>(code);
pc = holder->instruction_start() + pc_offset;
*pc_address = pc;
if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
*constant_pool_address = holder->constant_pool();
}
if (code == holder) return;
holder = reinterpret_cast<Code*>(code);
pc = holder->instruction_start() + pc_offset;
*pc_address = pc;
if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
*constant_pool_address = holder->constant_pool();
}
}
......@@ -873,9 +872,8 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
uint8_t* safepoint_bits = safepoint_entry.bits();
safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
// Visit the rest of the parameters.
if (!is_js_to_wasm() && !is_wasm()) {
// Non-WASM frames have tagged values as parameters.
// Visit the rest of the parameters if they are tagged.
if (code->has_tagged_params()) {
v->VisitPointers(parameters_base, parameters_limit);
}
......@@ -892,8 +890,8 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
IteratePc(v, pc_address(), constant_pool_address(), code);
if (!is_wasm() && !is_wasm_to_js()) {
// Visit the context in stub frame and JavaScript frame.
// Visit the function in JavaScript frame.
// If this frame has JavaScript ABI, visit the context (in stub and JS
// frames) and the function (in JS frames).
v->VisitPointers(frame_header_base, frame_header_limit);
}
}
......@@ -2042,10 +2040,15 @@ void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
}
void InternalFrame::Iterate(ObjectVisitor* v) const {
// Internal frames only have object pointers on the expression stack
// as they never have any arguments.
IterateExpressions(v);
IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
Code* code = LookupCode();
IteratePc(v, pc_address(), constant_pool_address(), code);
// Internal frames typically do not receive any arguments, hence their stack
// only contains tagged pointers.
// We are misusing the has_tagged_params flag here to tell us whether
// the full stack frame contains only tagged pointers or only raw values.
// This is used for the WasmCompileLazy builtin, where we actually pass
// untagged arguments and also store untagged values on the stack.
if (code->has_tagged_params()) IterateExpressions(v);
}
......
......@@ -4916,6 +4916,16 @@ inline void Code::set_is_crankshafted(bool value) {
WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
inline bool Code::has_tagged_params() {
int flags = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
return HasTaggedStackField::decode(flags);
}
inline void Code::set_has_tagged_params(bool value) {
int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
int updated = HasTaggedStackField::update(previous, value);
WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
inline bool Code::is_turbofanned() {
return IsTurbofannedField::decode(
......
......@@ -5004,6 +5004,11 @@ class Code: public HeapObject {
inline bool is_hydrogen_stub(); // Crankshafted, but not a function.
inline void set_is_crankshafted(bool value);
// [has_tagged_params]: For compiled code or builtins: Tells whether the
// outgoing parameters of this code are tagged pointers. True for other kinds.
inline bool has_tagged_params();
inline void set_has_tagged_params(bool value);
// [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
// code object was generated by the TurboFan optimizing compiler.
inline bool is_turbofanned();
......@@ -5379,11 +5384,12 @@ class Code: public HeapObject {
// KindSpecificFlags2 layout (ALL)
static const int kIsCrankshaftedBit = 0;
class IsCrankshaftedField: public BitField<bool,
kIsCrankshaftedBit, 1> {}; // NOLINT
class IsCrankshaftedField : public BitField<bool, kIsCrankshaftedBit, 1> {};
static const int kHasTaggedStackBit = kIsCrankshaftedBit + 1;
class HasTaggedStackField : public BitField<bool, kHasTaggedStackBit, 1> {};
// KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
static const int kSafepointTableOffsetFirstBit = kHasTaggedStackBit + 1;
static const int kSafepointTableOffsetBitCount = 30;
STATIC_ASSERT(kSafepointTableOffsetFirstBit +
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment