Commit 5fa423d7 authored by eholk's avatar eholk Committed by Commit bot

[wasm] sundry trap handler fixes

This CL includes several small bug fixes for trap handlers. Among the changes:

* Use the correct representation for ProtectedLoads, enabling protected loads of
  floating point types.

* Including the protected instruction list in what gets serialized for Code
  objects. This is needed to allow deserialization for Wasm modules to work.

* Get the context needed to through and exception from the Isolate rather than
  getting it as a parameter to the Protected instructions. Passing it in as an
  argument is problematic when code is compiled ahead of time, as the context
  may not be known yet. The new approach is similar to how it works for TrapIf
  and TrapUnless.

BUG= https://bugs.chromium.org/p/v8/issues/detail?id=5277

Review-Url: https://codereview.chromium.org/2591903002
Cr-Commit-Position: refs/heads/master@{#41907}
parent c46f98bc
......@@ -839,7 +839,9 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
if (node->opcode() == IrOpcode::kStore ||
node->opcode() == IrOpcode::kUnalignedStore ||
node->opcode() == IrOpcode::kCheckedStore ||
node->opcode() == IrOpcode::kCall) {
node->opcode() == IrOpcode::kCall ||
node->opcode() == IrOpcode::kProtectedLoad ||
node->opcode() == IrOpcode::kProtectedStore) {
++effect_level;
}
SetEffectLevel(node, effect_level);
......@@ -1433,8 +1435,11 @@ void InstructionSelector::VisitNode(Node* node) {
}
case IrOpcode::kAtomicStore:
return VisitAtomicStore(node);
case IrOpcode::kProtectedLoad:
case IrOpcode::kProtectedLoad: {
LoadRepresentation type = LoadRepresentationOf(node->op());
MarkAsRepresentation(type.representation(), node);
return VisitProtectedLoad(node);
}
case IrOpcode::kUnsafePointerAdd:
MarkAsRepresentation(MachineType::PointerRepresentation(), node);
return VisitUnsafePointerAdd(node);
......
......@@ -483,41 +483,41 @@ struct MachineOperatorGlobalCache {
OVERFLOW_OP_LIST(OVERFLOW_OP)
#undef OVERFLOW_OP
#define LOAD(Type) \
struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
Load##Type##Operator() \
: Operator1<LoadRepresentation>( \
IrOpcode::kLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"Load", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
struct UnalignedLoad##Type##Operator final \
: public Operator1<UnalignedLoadRepresentation> { \
UnalignedLoad##Type##Operator() \
: Operator1<UnalignedLoadRepresentation>( \
IrOpcode::kUnalignedLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"UnalignedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
struct CheckedLoad##Type##Operator final \
: public Operator1<CheckedLoadRepresentation> { \
CheckedLoad##Type##Operator() \
: Operator1<CheckedLoadRepresentation>( \
IrOpcode::kCheckedLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"CheckedLoad", 3, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
struct ProtectedLoad##Type##Operator final \
: public Operator1<LoadRepresentation> { \
ProtectedLoad##Type##Operator() \
: Operator1<LoadRepresentation>( \
IrOpcode::kProtectedLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"ProtectedLoad", 4, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
Load##Type##Operator kLoad##Type; \
UnalignedLoad##Type##Operator kUnalignedLoad##Type; \
CheckedLoad##Type##Operator kCheckedLoad##Type; \
#define LOAD(Type) \
struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
Load##Type##Operator() \
: Operator1<LoadRepresentation>( \
IrOpcode::kLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"Load", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
struct UnalignedLoad##Type##Operator final \
: public Operator1<UnalignedLoadRepresentation> { \
UnalignedLoad##Type##Operator() \
: Operator1<UnalignedLoadRepresentation>( \
IrOpcode::kUnalignedLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"UnalignedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
struct CheckedLoad##Type##Operator final \
: public Operator1<CheckedLoadRepresentation> { \
CheckedLoad##Type##Operator() \
: Operator1<CheckedLoadRepresentation>( \
IrOpcode::kCheckedLoad, \
Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
"CheckedLoad", 3, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
struct ProtectedLoad##Type##Operator final \
: public Operator1<LoadRepresentation> { \
ProtectedLoad##Type##Operator() \
: Operator1<LoadRepresentation>( \
IrOpcode::kProtectedLoad, \
Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 3, 1, \
1, 1, 1, 0, MachineType::Type()) {} \
}; \
Load##Type##Operator kLoad##Type; \
UnalignedLoad##Type##Operator kUnalignedLoad##Type; \
CheckedLoad##Type##Operator kCheckedLoad##Type; \
ProtectedLoad##Type##Operator kProtectedLoad##Type;
MACHINE_TYPE_LIST(LOAD)
#undef LOAD
......@@ -589,7 +589,7 @@ struct MachineOperatorGlobalCache {
: Operator1<StoreRepresentation>( \
IrOpcode::kProtectedStore, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"Store", 5, 1, 1, 0, 1, 0, \
"Store", 4, 1, 1, 0, 1, 0, \
StoreRepresentation(MachineRepresentation::Type, \
kNoWriteBarrier)) {} \
}; \
......
......@@ -91,7 +91,9 @@ void MemoryOptimizer::VisitNode(Node* node, AllocationState const* state) {
case IrOpcode::kDeoptimizeUnless:
case IrOpcode::kIfException:
case IrOpcode::kLoad:
case IrOpcode::kProtectedLoad:
case IrOpcode::kStore:
case IrOpcode::kProtectedStore:
case IrOpcode::kRetain:
case IrOpcode::kUnsafePointerAdd:
return VisitOtherEffect(node, state);
......
......@@ -3078,11 +3078,10 @@ Node* WasmGraphBuilder::LoadMem(wasm::ValueType type, MachineType memtype,
jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) {
if (FLAG_wasm_trap_handler && kTrapHandlerSupported) {
DCHECK(FLAG_wasm_guard_pages);
Node* context = HeapConstant(module_->instance->context);
Node* position_node = jsgraph()->Int32Constant(position);
load = graph()->NewNode(jsgraph()->machine()->ProtectedLoad(memtype),
MemBuffer(offset), index, context, position_node,
*effect_, *control_);
MemBuffer(offset), index, position_node, *effect_,
*control_);
} else {
load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
MemBuffer(offset), index, *effect_, *control_);
......@@ -3138,12 +3137,10 @@ Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
if (aligned ||
jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
if (FLAG_wasm_trap_handler && kTrapHandlerSupported) {
Node* context = HeapConstant(module_->instance->context);
Node* position_node = jsgraph()->Int32Constant(position);
store = graph()->NewNode(
jsgraph()->machine()->ProtectedStore(memtype.representation()),
MemBuffer(offset), index, val, context, position_node, *effect_,
*control_);
MemBuffer(offset), index, val, position_node, *effect_, *control_);
} else {
StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
store =
......
......@@ -271,13 +271,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
class WasmOutOfLineTrap final : public OutOfLineCode {
public:
WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided,
Register context, int32_t position)
int32_t position, Instruction* instr)
: OutOfLineCode(gen),
gen_(gen),
pc_(pc),
frame_elided_(frame_elided),
context_(context),
position_(position) {}
position_(position),
instr_(instr) {}
// TODO(eholk): Refactor this method to take the code generator as a
// parameter.
......@@ -294,27 +294,32 @@ class WasmOutOfLineTrap final : public OutOfLineCode {
int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id);
__ Push(Smi::FromInt(trap_reason));
__ Push(Smi::FromInt(position_));
__ Move(rsi, context_);
__ Move(rsi, gen_->isolate()->native_context());
__ CallRuntime(Runtime::kThrowWasmError);
if (instr_->reference_map() != nullptr) {
gen_->RecordSafepoint(instr_->reference_map(), Safepoint::kSimple, 0,
Safepoint::kNoLazyDeopt);
}
}
private:
CodeGenerator* gen_;
int pc_;
bool frame_elided_;
Register context_;
int32_t position_;
Instruction* instr_;
};
void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, X64OperandConverter& i,
int pc) {
X64MemoryProtection protection =
InstructionCode opcode, size_t input_count,
X64OperandConverter& i, int pc, Instruction* instr) {
const X64MemoryProtection protection =
static_cast<X64MemoryProtection>(MiscField::decode(opcode));
if (protection == X64MemoryProtection::kProtected) {
bool frame_elided = !codegen->frame_access_state()->has_frame();
new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, i.InputRegister(2),
i.InputInt32(3));
const bool frame_elided = !codegen->frame_access_state()->has_frame();
const int32_t position = i.InputInt32(input_count - 1);
new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position, instr);
}
}
} // namespace
......@@ -1853,25 +1858,31 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg);
break;
case kX64Movsxbl:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movsxbl);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
break;
case kX64Movzxbl:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movzxbl);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
break;
case kX64Movsxbq:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movsxbq);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
case kX64Movzxbq:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movzxbq);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
break;
case kX64Movb: {
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
if (HasImmediateInput(instr, index)) {
......@@ -1879,29 +1890,34 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} else {
__ movb(operand, i.InputRegister(index));
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
}
case kX64Movsxwl:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movsxwl);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
break;
case kX64Movzxwl:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movzxwl);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
break;
case kX64Movsxwq:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movsxwq);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
case kX64Movzxwq:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movzxwq);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
break;
case kX64Movw: {
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
if (HasImmediateInput(instr, index)) {
......@@ -1909,10 +1925,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} else {
__ movw(operand, i.InputRegister(index));
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
}
case kX64Movl:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
if (instr->HasOutput()) {
if (instr->addressing_mode() == kMode_None) {
if (instr->InputAt(0)->IsRegister()) {
......@@ -1923,7 +1940,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} else {
__ movl(i.OutputRegister(), i.MemoryOperand());
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
__ AssertZeroExtended(i.OutputRegister());
} else {
size_t index = 0;
......@@ -1933,14 +1949,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} else {
__ movl(operand, i.InputRegister(index));
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
}
break;
case kX64Movsxlq:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
ASSEMBLE_MOVX(movsxlq);
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
case kX64Movq:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
if (instr->HasOutput()) {
__ movq(i.OutputRegister(), i.MemoryOperand());
} else {
......@@ -1952,9 +1970,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ movq(operand, i.InputRegister(index));
}
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
case kX64Movss:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
if (instr->HasOutput()) {
__ movss(i.OutputDoubleRegister(), i.MemoryOperand());
} else {
......@@ -1962,9 +1981,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Operand operand = i.MemoryOperand(&index);
__ movss(operand, i.InputDoubleRegister(index));
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
case kX64Movsd:
EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
__ pc_offset(), instr);
if (instr->HasOutput()) {
__ Movsd(i.OutputDoubleRegister(), i.MemoryOperand());
} else {
......@@ -1972,7 +1992,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Operand operand = i.MemoryOperand(&index);
__ Movsd(operand, i.InputDoubleRegister(index));
}
EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset());
break;
case kX64BitcastFI:
if (instr->InputAt(0)->IsFPStackSlot()) {
......
......@@ -179,7 +179,7 @@ class X64OperandGenerator final : public OperandGenerator {
};
namespace {
ArchOpcode GetLoadOpcode(LoadRepresentation load_rep, bool protect) {
ArchOpcode GetLoadOpcode(LoadRepresentation load_rep) {
ArchOpcode opcode = kArchNop;
switch (load_rep.representation()) {
case MachineRepresentation::kFloat32:
......@@ -251,38 +251,23 @@ void InstructionSelector::VisitLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
X64OperandGenerator g(this);
const bool protect = false;
ArchOpcode opcode = GetLoadOpcode(load_rep, protect);
ArchOpcode opcode = GetLoadOpcode(load_rep);
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node);
InstructionOperand inputs[3];
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
InstructionCode code = opcode | AddressingModeField::encode(mode);
if (node->opcode() == IrOpcode::kProtectedLoad) {
code |= MiscField::encode(X64MemoryProtection::kProtected);
// Add the source position as an input
inputs[input_count++] = g.UseImmediate(node->InputAt(2));
}
Emit(code, 1, outputs, input_count, inputs);
}
void InstructionSelector::VisitProtectedLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
X64OperandGenerator g(this);
const bool protect = true;
ArchOpcode opcode = GetLoadOpcode(load_rep, protect);
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node);
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
// Add the context parameter as an input.
inputs[input_count++] = g.UseUniqueRegister(node->InputAt(2));
// Add the source position as an input
inputs[input_count++] = g.UseImmediate(node->InputAt(3));
InstructionCode code = opcode | AddressingModeField::encode(mode) |
MiscField::encode(X64MemoryProtection::kProtected);
Emit(code, 1, outputs, input_count, inputs);
}
void InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); }
void InstructionSelector::VisitStore(Node* node) {
X64OperandGenerator g(this);
......@@ -347,13 +332,12 @@ void InstructionSelector::VisitStore(Node* node) {
void InstructionSelector::VisitProtectedStore(Node* node) {
X64OperandGenerator g(this);
Node* value = node->InputAt(2);
Node* context = node->InputAt(3);
Node* position = node->InputAt(4);
Node* position = node->InputAt(3);
StoreRepresentation store_rep = StoreRepresentationOf(node->op());
ArchOpcode opcode = GetStoreOpcode(store_rep);
InstructionOperand inputs[6];
InstructionOperand inputs[5];
size_t input_count = 0;
AddressingMode addressing_mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
......@@ -362,7 +346,6 @@ void InstructionSelector::VisitProtectedStore(Node* node) {
InstructionOperand value_operand =
g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
inputs[input_count++] = value_operand;
inputs[input_count++] = g.UseRegister(context);
inputs[input_count++] = g.UseImmediate(position);
Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs);
}
......
......@@ -1657,6 +1657,7 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
code->set_prologue_offset(prologue_offset);
code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size);
code->set_builtin_index(-1);
code->set_protected_instructions(*empty_fixed_array());
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
code->set_marked_for_deoptimization(false);
......
......@@ -360,7 +360,10 @@ class Code::BodyDescriptor final : public BodyDescriptorBase {
kSourcePositionTableOffset);
STATIC_ASSERT(kSourcePositionTableOffset + kPointerSize ==
kTypeFeedbackInfoOffset);
STATIC_ASSERT(kTypeFeedbackInfoOffset + kPointerSize == kNextCodeLinkOffset);
STATIC_ASSERT(kTypeFeedbackInfoOffset + kPointerSize ==
kProtectedInstructionOffset);
STATIC_ASSERT(kProtectedInstructionOffset + kPointerSize ==
kNextCodeLinkOffset);
static bool IsValidSlot(HeapObject* obj, int offset) {
// Slots in code can't be invalid because we never trim code objects.
......
......@@ -6838,6 +6838,7 @@ void Code::WipeOutHeader() {
}
WRITE_FIELD(this, kNextCodeLinkOffset, NULL);
WRITE_FIELD(this, kGCMetadataOffset, NULL);
WRITE_FIELD(this, kProtectedInstructionOffset, NULL);
}
......@@ -6921,6 +6922,7 @@ int Code::SizeIncludingMetadata() {
size += deoptimization_data()->Size();
size += handler_table()->Size();
if (kind() == FUNCTION) size += source_position_table()->Size();
size += protected_instructions()->Size();
return size;
}
......
......@@ -5491,7 +5491,10 @@ class Code: public HeapObject {
// For FUNCTION kind, we store the type feedback info here.
static const int kTypeFeedbackInfoOffset =
kSourcePositionTableOffset + kPointerSize;
static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
static const int kProtectedInstructionOffset =
kTypeFeedbackInfoOffset + kPointerSize;
static const int kNextCodeLinkOffset =
kProtectedInstructionOffset + kPointerSize;
static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
......@@ -5504,12 +5507,10 @@ class Code: public HeapObject {
static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
static const int kBuiltinIndexOffset =
kConstantPoolOffset + kConstantPoolSize;
static const int kProtectedInstructionOffset = kBuiltinIndexOffset + kIntSize;
static const int kHeaderPaddingStart = kBuiltinIndexOffset + kIntSize;
enum TrapFields { kTrapCodeOffset, kTrapLandingOffset, kTrapDataSize };
static const int kHeaderPaddingStart =
kProtectedInstructionOffset + kPointerSize;
// Add padding to align the instruction start following right after
// the Code object header.
......
......@@ -1316,7 +1316,7 @@ class WasmInstanceBuilder {
}
FixedArray* protected_instructions = code->protected_instructions();
DCHECK(protected_instructions != nullptr);
Zone zone(isolate_->allocator(), "Wasm Module");
ZoneVector<trap_handler::ProtectedInstructionData> unpacked(&zone);
for (int i = 0; i < protected_instructions->length();
......
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