summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/wasm-compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/wasm-compiler.cc')
-rw-r--r--deps/v8/src/compiler/wasm-compiler.cc712
1 files changed, 429 insertions, 283 deletions
diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc
index 3396214e58..2da7177ece 100644
--- a/deps/v8/src/compiler/wasm-compiler.cc
+++ b/deps/v8/src/compiler/wasm-compiler.cc
@@ -14,6 +14,7 @@
#include "src/codegen/assembler-inl.h"
#include "src/codegen/assembler.h"
#include "src/codegen/code-factory.h"
+#include "src/codegen/compiler.h"
#include "src/codegen/interface-descriptors.h"
#include "src/codegen/optimized-compilation-info.h"
#include "src/compiler/backend/code-generator.h"
@@ -276,8 +277,9 @@ Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects,
}
Node* WasmGraphBuilder::RefNull() {
- return LOAD_INSTANCE_FIELD(NullValue,
- MachineType::TypeCompressedTaggedPointer());
+ Node* isolate_root = LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+ return LOAD_TAGGED_POINTER(
+ isolate_root, IsolateData::root_slot_offset(RootIndex::kNullValue));
}
Node* WasmGraphBuilder::RefFunc(uint32_t function_index) {
@@ -2195,8 +2197,8 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index,
graph()->NewNode(m->I32x4ExtractLane(3), value));
break;
case wasm::kWasmAnyRef:
- case wasm::kWasmAnyFunc:
- case wasm::kWasmExceptRef:
+ case wasm::kWasmFuncRef:
+ case wasm::kWasmExnRef:
STORE_FIXED_ARRAY_SLOT_ANY(values_array, index, value);
++index;
break;
@@ -2334,8 +2336,8 @@ Node** WasmGraphBuilder::GetExceptionValues(
BuildDecodeException32BitValue(values_array, &index));
break;
case wasm::kWasmAnyRef:
- case wasm::kWasmAnyFunc:
- case wasm::kWasmExceptRef:
+ case wasm::kWasmFuncRef:
+ case wasm::kWasmExnRef:
value = LOAD_FIXED_ARRAY_SLOT_ANY(values_array, index);
++index;
break;
@@ -2853,25 +2855,69 @@ Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets,
Node* WasmGraphBuilder::CallIndirect(uint32_t table_index, uint32_t sig_index,
Node** args, Node*** rets,
wasm::WasmCodePosition position) {
- if (table_index == 0) {
- return BuildIndirectCall(sig_index, args, rets, position, kCallContinues);
- }
return BuildIndirectCall(table_index, sig_index, args, rets, position,
kCallContinues);
}
-Node* WasmGraphBuilder::BuildIndirectCall(uint32_t sig_index, Node** args,
+void WasmGraphBuilder::LoadIndirectFunctionTable(uint32_t table_index,
+ Node** ift_size,
+ Node** ift_sig_ids,
+ Node** ift_targets,
+ Node** ift_instances) {
+ if (table_index == 0) {
+ *ift_size =
+ LOAD_INSTANCE_FIELD(IndirectFunctionTableSize, MachineType::Uint32());
+ *ift_sig_ids = LOAD_INSTANCE_FIELD(IndirectFunctionTableSigIds,
+ MachineType::Pointer());
+ *ift_targets = LOAD_INSTANCE_FIELD(IndirectFunctionTableTargets,
+ MachineType::Pointer());
+ *ift_instances = LOAD_INSTANCE_FIELD(
+ IndirectFunctionTableRefs, MachineType::TypeCompressedTaggedPointer());
+ return;
+ }
+
+ Node* ift_tables = LOAD_INSTANCE_FIELD(
+ IndirectFunctionTables, MachineType::TypeCompressedTaggedPointer());
+ Node* ift_table = LOAD_FIXED_ARRAY_SLOT_ANY(ift_tables, table_index);
+
+ *ift_size = LOAD_RAW(
+ ift_table,
+ wasm::ObjectAccess::ToTagged(WasmIndirectFunctionTable::kSizeOffset),
+ MachineType::Int32());
+
+ *ift_sig_ids = LOAD_RAW(
+ ift_table,
+ wasm::ObjectAccess::ToTagged(WasmIndirectFunctionTable::kSigIdsOffset),
+ MachineType::Pointer());
+
+ *ift_targets = LOAD_RAW(
+ ift_table,
+ wasm::ObjectAccess::ToTagged(WasmIndirectFunctionTable::kTargetsOffset),
+ MachineType::Pointer());
+
+ *ift_instances = LOAD_RAW(
+ ift_table,
+ wasm::ObjectAccess::ToTagged(WasmIndirectFunctionTable::kRefsOffset),
+ MachineType::TypeCompressedTaggedPointer());
+}
+
+Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index,
+ uint32_t sig_index, Node** args,
Node*** rets,
wasm::WasmCodePosition position,
IsReturnCall continuation) {
DCHECK_NOT_NULL(args[0]);
DCHECK_NOT_NULL(env_);
- // Assume only one table for now.
- wasm::FunctionSig* sig = env_->module->signatures[sig_index];
+ // First we have to load the table.
+ Node* ift_size;
+ Node* ift_sig_ids;
+ Node* ift_targets;
+ Node* ift_instances;
+ LoadIndirectFunctionTable(table_index, &ift_size, &ift_sig_ids, &ift_targets,
+ &ift_instances);
- Node* ift_size =
- LOAD_INSTANCE_FIELD(IndirectFunctionTableSize, MachineType::Uint32());
+ wasm::FunctionSig* sig = env_->module->signatures[sig_index];
MachineOperatorBuilder* machine = mcgraph()->machine();
Node* key = args[0];
@@ -2894,9 +2940,6 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t sig_index, Node** args,
}
// Load signature from the table and check.
- Node* ift_sig_ids =
- LOAD_INSTANCE_FIELD(IndirectFunctionTableSigIds, MachineType::Pointer());
-
int32_t expected_sig_id = env_->module->signature_ids[sig_index];
Node* int32_scaled_key = Uint32ToUintptr(
graph()->NewNode(machine->Word32Shl(), key, Int32Constant(2)));
@@ -2909,11 +2952,6 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t sig_index, Node** args,
TrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position);
- Node* ift_targets =
- LOAD_INSTANCE_FIELD(IndirectFunctionTableTargets, MachineType::Pointer());
- Node* ift_instances = LOAD_INSTANCE_FIELD(
- IndirectFunctionTableRefs, MachineType::TypeCompressedTaggedPointer());
-
Node* tagged_scaled_key;
if (kTaggedSize == kInt32Size) {
tagged_scaled_key = int32_scaled_key;
@@ -2955,48 +2993,6 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t sig_index, Node** args,
}
}
-Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index,
- uint32_t sig_index, Node** args,
- Node*** rets,
- wasm::WasmCodePosition position,
- IsReturnCall continuation) {
- DCHECK_NOT_NULL(args[0]);
- Node* entry_index = args[0];
- DCHECK_NOT_NULL(env_);
- BoundsCheckTable(table_index, entry_index, position, wasm::kTrapFuncInvalid,
- nullptr);
-
- DCHECK(Smi::IsValid(table_index));
- DCHECK(Smi::IsValid(sig_index));
- Node* runtime_args[]{
- graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)),
- BuildChangeUint31ToSmi(entry_index),
- graph()->NewNode(mcgraph()->common()->NumberConstant(sig_index))};
-
- Node* target_instance = BuildCallToRuntime(
- Runtime::kWasmIndirectCallCheckSignatureAndGetTargetInstance,
- runtime_args, arraysize(runtime_args));
-
- // We reuse the runtime_args array here, even though we only need the first
- // two arguments.
- Node* call_target = BuildCallToRuntime(
- Runtime::kWasmIndirectCallGetTargetAddress, runtime_args, 2);
-
- wasm::FunctionSig* sig = env_->module->signatures[sig_index];
- args[0] = call_target;
- const UseRetpoline use_retpoline =
- untrusted_code_mitigations_ ? kRetpoline : kNoRetpoline;
-
- switch (continuation) {
- case kCallContinues:
- return BuildWasmCall(sig, args, rets, position, target_instance,
- use_retpoline);
- case kReturnCall:
- return BuildWasmReturnCall(sig, args, position, target_instance,
- use_retpoline);
- }
-}
-
Node* WasmGraphBuilder::ReturnCall(uint32_t index, Node** args,
wasm::WasmCodePosition position) {
DCHECK_NULL(args[0]);
@@ -3019,9 +3015,6 @@ Node* WasmGraphBuilder::ReturnCall(uint32_t index, Node** args,
Node* WasmGraphBuilder::ReturnCallIndirect(uint32_t table_index,
uint32_t sig_index, Node** args,
wasm::WasmCodePosition position) {
- if (table_index == 0) {
- return BuildIndirectCall(sig_index, args, nullptr, position, kReturnCall);
- }
return BuildIndirectCall(table_index, sig_index, args, nullptr, position,
kReturnCall);
}
@@ -3324,13 +3317,6 @@ Node* WasmGraphBuilder::CurrentMemoryPages() {
return result;
}
-Node* WasmGraphBuilder::BuildLoadBuiltinFromInstance(int builtin_index) {
- DCHECK(Builtins::IsBuiltinId(builtin_index));
- Node* isolate_root = LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
- return LOAD_TAGGED_POINTER(isolate_root,
- IsolateData::builtin_slot_offset(builtin_index));
-}
-
// Only call this function for code which is not reused across instantiations,
// as we do not patch the embedded js_context.
Node* WasmGraphBuilder::BuildCallToRuntimeWithContext(
@@ -3492,7 +3478,7 @@ void WasmGraphBuilder::GetTableBaseAndOffset(uint32_t table_index,
wasm::ObjectAccess::ElementOffsetInTaggedFixedArray(0)));
}
-Node* WasmGraphBuilder::GetTable(uint32_t table_index, Node* index,
+Node* WasmGraphBuilder::TableGet(uint32_t table_index, Node* index,
wasm::WasmCodePosition position) {
if (env_->module->tables[table_index].type == wasm::kWasmAnyRef) {
Node* base = nullptr;
@@ -3501,7 +3487,7 @@ Node* WasmGraphBuilder::GetTable(uint32_t table_index, Node* index,
return LOAD_RAW_NODE_OFFSET(base, offset,
MachineType::TypeCompressedTagged());
}
- // We access anyfunc tables through runtime calls.
+ // We access funcref tables through runtime calls.
WasmTableGetDescriptor interface_descriptor;
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), // zone
@@ -3521,7 +3507,7 @@ Node* WasmGraphBuilder::GetTable(uint32_t table_index, Node* index,
Effect(), Control())));
}
-Node* WasmGraphBuilder::SetTable(uint32_t table_index, Node* index, Node* val,
+Node* WasmGraphBuilder::TableSet(uint32_t table_index, Node* index, Node* val,
wasm::WasmCodePosition position) {
if (env_->module->tables[table_index].type == wasm::kWasmAnyRef) {
Node* base = nullptr;
@@ -3530,7 +3516,7 @@ Node* WasmGraphBuilder::SetTable(uint32_t table_index, Node* index, Node* val,
return STORE_RAW_NODE_OFFSET(
base, offset, val, MachineRepresentation::kTagged, kFullWriteBarrier);
} else {
- // We access anyfunc tables through runtime calls.
+ // We access funcref tables through runtime calls.
WasmTableSetDescriptor interface_descriptor;
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), // zone
@@ -4000,6 +3986,30 @@ Node* WasmGraphBuilder::S128Zero() {
Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
has_simd_ = true;
switch (opcode) {
+ case wasm::kExprF64x2Splat:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Splat(), inputs[0]);
+ case wasm::kExprF64x2Abs:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Abs(), inputs[0]);
+ case wasm::kExprF64x2Neg:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Neg(), inputs[0]);
+ case wasm::kExprF64x2Eq:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Eq(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Ne:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Ne(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Lt:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Lt(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Le:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Le(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Gt:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Lt(), inputs[1],
+ inputs[0]);
+ case wasm::kExprF64x2Ge:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Le(), inputs[1],
+ inputs[0]);
case wasm::kExprF32x4Splat:
return graph()->NewNode(mcgraph()->machine()->F32x4Splat(), inputs[0]);
case wasm::kExprF32x4SConvertI32x4:
@@ -4054,6 +4064,49 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprF32x4Ge:
return graph()->NewNode(mcgraph()->machine()->F32x4Le(), inputs[1],
inputs[0]);
+ case wasm::kExprI64x2Splat:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Splat(), inputs[0]);
+ case wasm::kExprI64x2Neg:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Neg(), inputs[0]);
+ case wasm::kExprI64x2Add:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Add(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2Sub:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Sub(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2Mul:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Mul(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2Eq:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Eq(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2Ne:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Ne(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2LtS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GtS(), inputs[1],
+ inputs[0]);
+ case wasm::kExprI64x2LeS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GeS(), inputs[1],
+ inputs[0]);
+ case wasm::kExprI64x2GtS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GtS(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2GeS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GeS(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2LtU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GtU(), inputs[1],
+ inputs[0]);
+ case wasm::kExprI64x2LeU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GeU(), inputs[1],
+ inputs[0]);
+ case wasm::kExprI64x2GtU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GtU(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2GeU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2GeU(), inputs[0],
+ inputs[1]);
case wasm::kExprI32x4Splat:
return graph()->NewNode(mcgraph()->machine()->I32x4Splat(), inputs[0]);
case wasm::kExprI32x4SConvertF32x4:
@@ -4305,6 +4358,10 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprS128Select:
return graph()->NewNode(mcgraph()->machine()->S128Select(), inputs[2],
inputs[0], inputs[1]);
+ case wasm::kExprS1x2AnyTrue:
+ return graph()->NewNode(mcgraph()->machine()->S1x2AnyTrue(), inputs[0]);
+ case wasm::kExprS1x2AllTrue:
+ return graph()->NewNode(mcgraph()->machine()->S1x2AllTrue(), inputs[0]);
case wasm::kExprS1x4AnyTrue:
return graph()->NewNode(mcgraph()->machine()->S1x4AnyTrue(), inputs[0]);
case wasm::kExprS1x4AllTrue:
@@ -4326,12 +4383,24 @@ Node* WasmGraphBuilder::SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane,
Node* const* inputs) {
has_simd_ = true;
switch (opcode) {
+ case wasm::kExprF64x2ExtractLane:
+ return graph()->NewNode(mcgraph()->machine()->F64x2ExtractLane(lane),
+ inputs[0]);
+ case wasm::kExprF64x2ReplaceLane:
+ return graph()->NewNode(mcgraph()->machine()->F64x2ReplaceLane(lane),
+ inputs[0], inputs[1]);
case wasm::kExprF32x4ExtractLane:
return graph()->NewNode(mcgraph()->machine()->F32x4ExtractLane(lane),
inputs[0]);
case wasm::kExprF32x4ReplaceLane:
return graph()->NewNode(mcgraph()->machine()->F32x4ReplaceLane(lane),
inputs[0], inputs[1]);
+ case wasm::kExprI64x2ExtractLane:
+ return graph()->NewNode(mcgraph()->machine()->I64x2ExtractLane(lane),
+ inputs[0]);
+ case wasm::kExprI64x2ReplaceLane:
+ return graph()->NewNode(mcgraph()->machine()->I64x2ReplaceLane(lane),
+ inputs[0], inputs[1]);
case wasm::kExprI32x4ExtractLane:
return graph()->NewNode(mcgraph()->machine()->I32x4ExtractLane(lane),
inputs[0]);
@@ -4359,6 +4428,14 @@ Node* WasmGraphBuilder::SimdShiftOp(wasm::WasmOpcode opcode, uint8_t shift,
Node* const* inputs) {
has_simd_ = true;
switch (opcode) {
+ case wasm::kExprI64x2Shl:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Shl(shift), inputs[0]);
+ case wasm::kExprI64x2ShrS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2ShrS(shift),
+ inputs[0]);
+ case wasm::kExprI64x2ShrU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2ShrU(shift),
+ inputs[0]);
case wasm::kExprI32x4Shl:
return graph()->NewNode(mcgraph()->machine()->I32x4Shl(shift), inputs[0]);
case wasm::kExprI32x4ShrS:
@@ -4612,6 +4689,11 @@ Node* WasmGraphBuilder::AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
return SetEffect(node);
}
+Node* WasmGraphBuilder::AtomicFence() {
+ return SetEffect(graph()->NewNode(mcgraph()->machine()->MemBarrier(),
+ Effect(), Control()));
+}
+
#undef ATOMIC_BINOP_LIST
#undef ATOMIC_CMP_EXCHG_LIST
#undef ATOMIC_LOAD_LIST
@@ -4636,8 +4718,19 @@ Node* WasmGraphBuilder::MemoryInit(uint32_t data_segment_index, Node* dst,
Node* src, Node* size,
wasm::WasmCodePosition position) {
CheckDataSegmentIsPassiveAndNotDropped(data_segment_index, position);
- Node* dst_fail = BoundsCheckMemRange(&dst, &size, position);
auto m = mcgraph()->machine();
+ auto common = mcgraph()->common();
+ Node* size_null_check =
+ graph()->NewNode(m->Word32Equal(), size, mcgraph()->Int32Constant(0));
+ Node* size_null_branch = graph()->NewNode(common->Branch(BranchHint::kFalse),
+ size_null_check, Control());
+
+ Node* size_null_etrue = Effect();
+ Node* size_null_if_false =
+ graph()->NewNode(common->IfFalse(), size_null_branch);
+ SetControl(size_null_if_false);
+
+ Node* dst_fail = BoundsCheckMemRange(&dst, &size, position);
Node* seg_index = Uint32Constant(data_segment_index);
Node* src_fail;
@@ -4679,9 +4772,16 @@ Node* WasmGraphBuilder::MemoryInit(uint32_t data_segment_index, Node* dst,
MachineType::Uint32()};
MachineSignature sig(0, 3, sig_types);
BuildCCall(&sig, function, dst, src, size);
- return TrapIfTrue(wasm::kTrapMemOutOfBounds,
- graph()->NewNode(m->Word32Or(), dst_fail, src_fail),
- position);
+ TrapIfTrue(wasm::kTrapMemOutOfBounds,
+ graph()->NewNode(m->Word32Or(), dst_fail, src_fail), position);
+ Node* size_null_if_true =
+ graph()->NewNode(common->IfTrue(), size_null_branch);
+
+ Node* merge = SetControl(
+ graph()->NewNode(common->Merge(2), size_null_if_true, Control()));
+ SetEffect(
+ graph()->NewNode(common->EffectPhi(2), size_null_etrue, Effect(), merge));
+ return merge;
}
Node* WasmGraphBuilder::DataDrop(uint32_t data_segment_index,
@@ -4699,16 +4799,19 @@ Node* WasmGraphBuilder::DataDrop(uint32_t data_segment_index,
Node* WasmGraphBuilder::MemoryCopy(Node* dst, Node* src, Node* size,
wasm::WasmCodePosition position) {
auto m = mcgraph()->machine();
- // The data must be copied backward if the regions overlap and src < dst. The
- // regions overlap if {src + size > dst && dst + size > src}. Since we already
- // test that {src < dst}, we know that {dst + size > src}, so this simplifies
- // to just {src + size > dst}. That sum can overflow, but if we subtract
- // {size} from both sides of the inequality we get the equivalent test
- // {size > dst - src}.
- Node* copy_backward = graph()->NewNode(
- m->Word32And(), graph()->NewNode(m->Uint32LessThan(), src, dst),
- graph()->NewNode(m->Uint32LessThan(),
- graph()->NewNode(m->Int32Sub(), dst, src), size));
+ auto common = mcgraph()->common();
+ // If size == 0, then memory.copy is a no-op.
+ Node* size_null_check =
+ graph()->NewNode(m->Word32Equal(), size, mcgraph()->Int32Constant(0));
+ Node* size_null_branch = graph()->NewNode(common->Branch(BranchHint::kFalse),
+ size_null_check, Control());
+
+ Node* size_null_etrue = Effect();
+ Node* size_null_if_false =
+ graph()->NewNode(common->IfFalse(), size_null_branch);
+ SetControl(size_null_if_false);
+ // The data must be copied backward if src < dst.
+ Node* copy_backward = graph()->NewNode(m->Uint32LessThan(), src, dst);
Node* dst_fail = BoundsCheckMemRange(&dst, &size, position);
@@ -4728,13 +4831,32 @@ Node* WasmGraphBuilder::MemoryCopy(Node* dst, Node* src, Node* size,
MachineType::Uint32()};
MachineSignature sig(0, 3, sig_types);
BuildCCall(&sig, function, dst, src, size);
- return TrapIfTrue(wasm::kTrapMemOutOfBounds,
- graph()->NewNode(m->Word32Or(), dst_fail, src_fail),
- position);
+ TrapIfTrue(wasm::kTrapMemOutOfBounds,
+ graph()->NewNode(m->Word32Or(), dst_fail, src_fail), position);
+ Node* size_null_if_true =
+ graph()->NewNode(common->IfTrue(), size_null_branch);
+
+ Node* merge = SetControl(
+ graph()->NewNode(common->Merge(2), size_null_if_true, Control()));
+ SetEffect(
+ graph()->NewNode(common->EffectPhi(2), size_null_etrue, Effect(), merge));
+ return merge;
}
Node* WasmGraphBuilder::MemoryFill(Node* dst, Node* value, Node* size,
wasm::WasmCodePosition position) {
+ auto machine = mcgraph()->machine();
+ auto common = mcgraph()->common();
+ // If size == 0, then memory.copy is a no-op.
+ Node* size_null_check = graph()->NewNode(machine->Word32Equal(), size,
+ mcgraph()->Int32Constant(0));
+ Node* size_null_branch = graph()->NewNode(common->Branch(BranchHint::kFalse),
+ size_null_check, Control());
+
+ Node* size_null_etrue = Effect();
+ Node* size_null_if_false =
+ graph()->NewNode(common->IfFalse(), size_null_branch);
+ SetControl(size_null_if_false);
Node* fail = BoundsCheckMemRange(&dst, &size, position);
Node* function = graph()->NewNode(mcgraph()->common()->ExternalConstant(
ExternalReference::wasm_memory_fill()));
@@ -4742,7 +4864,15 @@ Node* WasmGraphBuilder::MemoryFill(Node* dst, Node* value, Node* size,
MachineType::Uint32()};
MachineSignature sig(0, 3, sig_types);
BuildCCall(&sig, function, dst, value, size);
- return TrapIfTrue(wasm::kTrapMemOutOfBounds, fail, position);
+ TrapIfTrue(wasm::kTrapMemOutOfBounds, fail, position);
+ Node* size_null_if_true =
+ graph()->NewNode(common->IfTrue(), size_null_branch);
+
+ Node* merge = SetControl(
+ graph()->NewNode(common->Merge(2), size_null_if_true, Control()));
+ SetEffect(
+ graph()->NewNode(common->EffectPhi(2), size_null_etrue, Effect(), merge));
+ return merge;
}
Node* WasmGraphBuilder::CheckElemSegmentIsPassiveAndNotDropped(
@@ -4789,13 +4919,13 @@ Node* WasmGraphBuilder::ElemDrop(uint32_t elem_segment_index,
mcgraph()->Int32Constant(1), Effect(), Control()));
}
-Node* WasmGraphBuilder::TableCopy(uint32_t table_src_index,
- uint32_t table_dst_index, Node* dst,
+Node* WasmGraphBuilder::TableCopy(uint32_t table_dst_index,
+ uint32_t table_src_index, Node* dst,
Node* src, Node* size,
wasm::WasmCodePosition position) {
Node* args[] = {
- graph()->NewNode(mcgraph()->common()->NumberConstant(table_src_index)),
graph()->NewNode(mcgraph()->common()->NumberConstant(table_dst_index)),
+ graph()->NewNode(mcgraph()->common()->NumberConstant(table_src_index)),
BuildConvertUint32ToSmiWithSaturation(dst, FLAG_wasm_max_table_size),
BuildConvertUint32ToSmiWithSaturation(src, FLAG_wasm_max_table_size),
BuildConvertUint32ToSmiWithSaturation(size, FLAG_wasm_max_table_size)};
@@ -4878,28 +5008,6 @@ void WasmGraphBuilder::RemoveBytecodePositionDecorator() {
}
namespace {
-bool must_record_function_compilation(Isolate* isolate) {
- return isolate->logger()->is_listening_to_code_events() ||
- isolate->is_profiling();
-}
-
-PRINTF_FORMAT(4, 5)
-void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
- Isolate* isolate, Handle<Code> code,
- const char* format, ...) {
- DCHECK(must_record_function_compilation(isolate));
-
- ScopedVector<char> buffer(128);
- va_list arguments;
- va_start(arguments, format);
- int len = VSNPrintF(buffer, format, arguments);
- CHECK_LT(0, len);
- va_end(arguments);
- Handle<String> name_str =
- isolate->factory()->NewStringFromAsciiChecked(buffer.begin());
- PROFILE(isolate, CodeCreateEvent(tag, AbstractCode::cast(*code), *name_str));
-}
-
class WasmWrapperGraphBuilder : public WasmGraphBuilder {
public:
WasmWrapperGraphBuilder(Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* sig,
@@ -4914,12 +5022,12 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* BuildAllocateHeapNumberWithValue(Node* value, Node* control) {
MachineOperatorBuilder* machine = mcgraph()->machine();
CommonOperatorBuilder* common = mcgraph()->common();
- Node* target = (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
- ? mcgraph()->RelocatableIntPtrConstant(
- wasm::WasmCode::kWasmAllocateHeapNumber,
- RelocInfo::WASM_STUB_CALL)
- : jsgraph()->HeapConstant(
- BUILTIN_CODE(isolate_, AllocateHeapNumber));
+ Node* target =
+ (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
+ ? mcgraph()->RelocatableIntPtrConstant(
+ wasm::WasmCode::kWasmAllocateHeapNumber,
+ RelocInfo::WASM_STUB_CALL)
+ : BuildLoadBuiltinFromInstance(Builtins::kAllocateHeapNumber);
if (!allocate_heap_number_operator_.is_set()) {
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), AllocateHeapNumberDescriptor(), 0,
@@ -4956,6 +5064,34 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return mcgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag);
}
+ Node* BuildLoadUndefinedValueFromInstance() {
+ if (undefined_value_node_ == nullptr) {
+ Node* isolate_root = graph()->NewNode(
+ mcgraph()->machine()->Load(MachineType::Pointer()),
+ instance_node_.get(),
+ mcgraph()->Int32Constant(WASM_INSTANCE_OBJECT_OFFSET(IsolateRoot)),
+ graph()->start(), graph()->start());
+ undefined_value_node_ = InsertDecompressionIfNeeded(
+ MachineType::TypeCompressedTaggedPointer(),
+ graph()->NewNode(
+ mcgraph()->machine()->Load(
+ MachineType::TypeCompressedTaggedPointer()),
+ isolate_root,
+ mcgraph()->Int32Constant(
+ IsolateData::root_slot_offset(RootIndex::kUndefinedValue)),
+ isolate_root, graph()->start()));
+ }
+ return undefined_value_node_.get();
+ }
+
+ Node* BuildLoadBuiltinFromInstance(int builtin_index) {
+ DCHECK(Builtins::IsBuiltinId(builtin_index));
+ Node* isolate_root =
+ LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+ return LOAD_TAGGED_POINTER(isolate_root,
+ IsolateData::builtin_slot_offset(builtin_index));
+ }
+
Node* BuildChangeInt32ToTagged(Node* value) {
MachineOperatorBuilder* machine = mcgraph()->machine();
CommonOperatorBuilder* common = mcgraph()->common();
@@ -5096,7 +5232,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
(stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
? mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmToNumber, RelocInfo::WASM_STUB_CALL)
- : jsgraph()->HeapConstant(BUILTIN_CODE(isolate_, ToNumber));
+ : BuildLoadBuiltinFromInstance(Builtins::kToNumber);
Node* result = SetEffect(
graph()->NewNode(mcgraph()->common()->Call(call_descriptor), stub_code,
@@ -5126,8 +5262,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
SetControl(is_heap_object.if_true);
Node* orig_effect = Effect();
- Node* undefined_node = LOAD_INSTANCE_FIELD(
- UndefinedValue, MachineType::TypeCompressedTaggedPointer());
+ Node* undefined_node = BuildLoadUndefinedValueFromInstance();
Node* check_undefined =
graph()->NewNode(machine->WordEqual(), value, undefined_node);
Node* effect_tagged = Effect();
@@ -5173,8 +5308,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
case wasm::kWasmF64:
return BuildChangeFloat64ToTagged(node);
case wasm::kWasmAnyRef:
- case wasm::kWasmAnyFunc:
- case wasm::kWasmExceptRef:
+ case wasm::kWasmFuncRef:
+ case wasm::kWasmExnRef:
return node;
default:
UNREACHABLE();
@@ -5196,7 +5331,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
(stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
? mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmI64ToBigInt, RelocInfo::WASM_STUB_CALL)
- : jsgraph()->HeapConstant(BUILTIN_CODE(isolate_, I64ToBigInt));
+ : BuildLoadBuiltinFromInstance(Builtins::kI64ToBigInt);
return SetEffect(
SetControl(graph()->NewNode(mcgraph()->common()->Call(call_descriptor),
@@ -5218,7 +5353,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
(stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
? mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmBigIntToI64, RelocInfo::WASM_STUB_CALL)
- : jsgraph()->HeapConstant(BUILTIN_CODE(isolate_, BigIntToI64));
+ : BuildLoadBuiltinFromInstance(Builtins::kBigIntToI64);
return SetEffect(SetControl(
graph()->NewNode(mcgraph()->common()->Call(call_descriptor), target,
@@ -5228,15 +5363,15 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* FromJS(Node* node, Node* js_context, wasm::ValueType type) {
DCHECK_NE(wasm::kWasmStmt, type);
- // The parameter is of type anyref or except_ref, we take it as is.
- if (type == wasm::kWasmAnyRef || type == wasm::kWasmExceptRef) {
+ // The parameter is of type anyref or exnref, we take it as is.
+ if (type == wasm::kWasmAnyRef || type == wasm::kWasmExnRef) {
return node;
}
- if (type == wasm::kWasmAnyFunc) {
+ if (type == wasm::kWasmFuncRef) {
Node* check =
BuildChangeSmiToInt32(SetEffect(BuildCallToRuntimeWithContext(
- Runtime::kWasmIsValidAnyFuncValue, js_context, &node, 1, effect_,
+ Runtime::kWasmIsValidFuncRefValue, js_context, &node, 1, effect_,
Control())));
Diamond type_check(graph(), mcgraph()->common(), check,
@@ -5471,8 +5606,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// The callable is passed as the last parameter, after WASM arguments.
Node* callable_node = Param(wasm_count + 1);
- Node* undefined_node = LOAD_INSTANCE_FIELD(
- UndefinedValue, MachineType::TypeCompressedTaggedPointer());
+ Node* undefined_node = BuildLoadUndefinedValueFromInstance();
Node* call = nullptr;
bool sloppy_receiver = true;
@@ -5811,22 +5945,26 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
}
void BuildCWasmEntry() {
- // Build the start and the JS parameter nodes.
- SetEffect(SetControl(Start(CWasmEntryParameters::kNumParameters + 5)));
+ // +1 offset for first parameter index being -1.
+ SetEffect(SetControl(Start(CWasmEntryParameters::kNumParameters + 1)));
- // Create parameter nodes (offset by 1 for the receiver parameter).
- Node* code_entry = Param(CWasmEntryParameters::kCodeEntry + 1);
- Node* object_ref_node = Param(CWasmEntryParameters::kObjectRef + 1);
- Node* arg_buffer = Param(CWasmEntryParameters::kArgumentsBuffer + 1);
+ Node* code_entry = Param(CWasmEntryParameters::kCodeEntry);
+ Node* object_ref = Param(CWasmEntryParameters::kObjectRef);
+ Node* arg_buffer = Param(CWasmEntryParameters::kArgumentsBuffer);
+ Node* c_entry_fp = Param(CWasmEntryParameters::kCEntryFp);
+
+ Node* fp_value = graph()->NewNode(mcgraph()->machine()->LoadFramePointer());
+ STORE_RAW(fp_value, TypedFrameConstants::kFirstPushedFrameValueOffset,
+ c_entry_fp, MachineType::PointerRepresentation(),
+ kNoWriteBarrier);
int wasm_arg_count = static_cast<int>(sig_->parameter_count());
- int arg_count =
- wasm_arg_count + 4; // code, object_ref_node, control, effect
+ int arg_count = wasm_arg_count + 4; // code, object_ref, control, effect
Node** args = Buffer(arg_count);
int pos = 0;
args[pos++] = code_entry;
- args[pos++] = object_ref_node;
+ args[pos++] = object_ref;
int offset = 0;
for (wasm::ValueType type : sig_->parameters()) {
@@ -5847,26 +5985,43 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* call = SetEffect(graph()->NewNode(
mcgraph()->common()->Call(call_descriptor), arg_count, args));
- // Store the return value.
- DCHECK_GE(1, sig_->return_count());
- if (sig_->return_count() == 1) {
+ Node* if_success = graph()->NewNode(mcgraph()->common()->IfSuccess(), call);
+ Node* if_exception =
+ graph()->NewNode(mcgraph()->common()->IfException(), call, call);
+
+ // Handle exception: return it.
+ SetControl(if_exception);
+ Return(if_exception);
+
+ // Handle success: store the return value(s).
+ SetControl(if_success);
+ pos = 0;
+ offset = 0;
+ for (wasm::ValueType type : sig_->returns()) {
StoreRepresentation store_rep(
- wasm::ValueTypes::MachineRepresentationFor(sig_->GetReturn()),
- kNoWriteBarrier);
+ wasm::ValueTypes::MachineRepresentationFor(type), kNoWriteBarrier);
+ Node* value = sig_->return_count() == 1
+ ? call
+ : graph()->NewNode(mcgraph()->common()->Projection(pos),
+ call, Control());
SetEffect(graph()->NewNode(mcgraph()->machine()->Store(store_rep),
- arg_buffer, Int32Constant(0), call, Effect(),
- Control()));
+ arg_buffer, Int32Constant(offset), value,
+ Effect(), Control()));
+ offset += wasm::ValueTypes::ElementSizeInBytes(type);
+ pos++;
}
+
Return(jsgraph()->SmiConstant(0));
if (mcgraph()->machine()->Is32() && ContainsInt64(sig_)) {
MachineRepresentation sig_reps[] = {
- MachineRepresentation::kWord32, // return value
- MachineRepresentation::kTagged, // receiver
- MachineRepresentation::kTagged, // arg0 (code)
- MachineRepresentation::kTagged // arg1 (buffer)
+ MachineType::PointerRepresentation(), // return value
+ MachineType::PointerRepresentation(), // target
+ MachineRepresentation::kTagged, // object_ref
+ MachineType::PointerRepresentation(), // argv
+ MachineType::PointerRepresentation() // c_entry_fp
};
- Signature<MachineRepresentation> c_entry_sig(1, 2, sig_reps);
+ Signature<MachineRepresentation> c_entry_sig(1, 4, sig_reps);
Int64Lowering r(mcgraph()->graph(), mcgraph()->machine(),
mcgraph()->common(), mcgraph()->zone(), &c_entry_sig);
r.LowerGraph();
@@ -5879,6 +6034,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Isolate* const isolate_;
JSGraph* jsgraph_;
StubCallMode stub_mode_;
+ SetOncePointer<Node> undefined_value_node_;
SetOncePointer<const Operator> allocate_heap_number_operator_;
wasm::WasmFeatures enabled_features_;
};
@@ -5901,27 +6057,25 @@ void AppendSignature(char* buffer, size_t max_name_len,
} // namespace
-MaybeHandle<Code> CompileJSToWasmWrapper(Isolate* isolate,
- wasm::FunctionSig* sig,
- bool is_import) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"),
- "CompileJSToWasmWrapper");
+std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
+ Isolate* isolate, wasm::FunctionSig* sig, bool is_import) {
//----------------------------------------------------------------------------
// Create the Graph.
//----------------------------------------------------------------------------
- Zone zone(isolate->allocator(), ZONE_NAME);
- Graph graph(&zone);
- CommonOperatorBuilder common(&zone);
+ std::unique_ptr<Zone> zone =
+ base::make_unique<Zone>(isolate->allocator(), ZONE_NAME);
+ Graph* graph = new (zone.get()) Graph(zone.get());
+ CommonOperatorBuilder common(zone.get());
MachineOperatorBuilder machine(
- &zone, MachineType::PointerRepresentation(),
+ zone.get(), MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
- JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
+ JSGraph jsgraph(isolate, graph, &common, nullptr, nullptr, &machine);
Node* control = nullptr;
Node* effect = nullptr;
- WasmWrapperGraphBuilder builder(&zone, &jsgraph, sig, nullptr,
+ WasmWrapperGraphBuilder builder(zone.get(), &jsgraph, sig, nullptr,
StubCallMode::kCallCodeObject,
wasm::WasmFeaturesFromIsolate(isolate));
builder.set_control_ptr(&control);
@@ -5929,73 +6083,66 @@ MaybeHandle<Code> CompileJSToWasmWrapper(Isolate* isolate,
builder.BuildJSToWasmWrapper(is_import);
//----------------------------------------------------------------------------
- // Run the compilation pipeline.
+ // Create the compilation job.
//----------------------------------------------------------------------------
static constexpr size_t kMaxNameLen = 128;
- char debug_name[kMaxNameLen] = "js_to_wasm:";
- AppendSignature(debug_name, kMaxNameLen, sig);
+ auto debug_name = std::unique_ptr<char[]>(new char[kMaxNameLen]);
+ memcpy(debug_name.get(), "js_to_wasm:", 12);
+ AppendSignature(debug_name.get(), kMaxNameLen, sig);
- // Schedule and compile to machine code.
int params = static_cast<int>(sig->parameter_count());
CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
- &zone, false, params + 1, CallDescriptor::kNoFlags);
+ zone.get(), false, params + 1, CallDescriptor::kNoFlags);
- MaybeHandle<Code> maybe_code = Pipeline::GenerateCodeForWasmHeapStub(
- isolate, incoming, &graph, Code::JS_TO_WASM_FUNCTION, debug_name,
- WasmAssemblerOptions());
- Handle<Code> code;
- if (!maybe_code.ToHandle(&code)) {
- return maybe_code;
- }
-#ifdef ENABLE_DISASSEMBLER
- if (FLAG_print_opt_code) {
- CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
- OFStream os(tracing_scope.file());
- code->Disassemble(debug_name, os);
- }
-#endif
-
- if (must_record_function_compilation(isolate)) {
- RecordFunctionCompilation(CodeEventListener::STUB_TAG, isolate, code, "%s",
- debug_name);
- }
-
- return code;
+ return Pipeline::NewWasmHeapStubCompilationJob(
+ isolate, incoming, std::move(zone), graph, Code::JS_TO_WASM_FUNCTION,
+ std::move(debug_name), WasmAssemblerOptions());
}
-WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> target,
- wasm::FunctionSig* expected_sig,
- bool has_bigint_feature) {
- if (WasmExportedFunction::IsWasmExportedFunction(*target)) {
- auto imported_function = WasmExportedFunction::cast(*target);
- auto func_index = imported_function.function_index();
- auto module = imported_function.instance().module();
+std::pair<WasmImportCallKind, Handle<JSReceiver>> ResolveWasmImportCall(
+ Handle<JSReceiver> callable, wasm::FunctionSig* expected_sig,
+ bool has_bigint_feature) {
+ if (WasmExportedFunction::IsWasmExportedFunction(*callable)) {
+ auto imported_function = Handle<WasmExportedFunction>::cast(callable);
+ auto func_index = imported_function->function_index();
+ auto module = imported_function->instance().module();
wasm::FunctionSig* imported_sig = module->functions[func_index].sig;
if (*imported_sig != *expected_sig) {
- return WasmImportCallKind::kLinkError;
+ return std::make_pair(WasmImportCallKind::kLinkError, callable);
}
- if (static_cast<uint32_t>(func_index) < module->num_imported_functions) {
- // TODO(wasm): this redirects all imported-reexported functions
- // through the call builtin. Fall through to JS function cases below?
- return WasmImportCallKind::kUseCallBuiltin;
+ if (static_cast<uint32_t>(func_index) >= module->num_imported_functions) {
+ return std::make_pair(WasmImportCallKind::kWasmToWasm, callable);
}
- return WasmImportCallKind::kWasmToWasm;
- }
- if (WasmCapiFunction::IsWasmCapiFunction(*target)) {
- WasmCapiFunction capi_function = WasmCapiFunction::cast(*target);
- if (!capi_function.IsSignatureEqual(expected_sig)) {
- return WasmImportCallKind::kLinkError;
+ Isolate* isolate = callable->GetIsolate();
+ // Resolve the short-cut to the underlying callable and continue.
+ Handle<WasmInstanceObject> instance(imported_function->instance(), isolate);
+ ImportedFunctionEntry entry(instance, func_index);
+ callable = handle(entry.callable(), isolate);
+ }
+ if (WasmJSFunction::IsWasmJSFunction(*callable)) {
+ auto js_function = Handle<WasmJSFunction>::cast(callable);
+ if (!js_function->MatchesSignature(expected_sig)) {
+ return std::make_pair(WasmImportCallKind::kLinkError, callable);
+ }
+ Isolate* isolate = callable->GetIsolate();
+ // Resolve the short-cut to the underlying callable and continue.
+ callable = handle(js_function->GetCallable(), isolate);
+ }
+ if (WasmCapiFunction::IsWasmCapiFunction(*callable)) {
+ auto capi_function = Handle<WasmCapiFunction>::cast(callable);
+ if (!capi_function->IsSignatureEqual(expected_sig)) {
+ return std::make_pair(WasmImportCallKind::kLinkError, callable);
}
- return WasmImportCallKind::kWasmToCapi;
+ return std::make_pair(WasmImportCallKind::kWasmToCapi, callable);
}
// Assuming we are calling to JS, check whether this would be a runtime error.
if (!wasm::IsJSCompatibleSignature(expected_sig, has_bigint_feature)) {
- return WasmImportCallKind::kRuntimeTypeError;
+ return std::make_pair(WasmImportCallKind::kRuntimeTypeError, callable);
}
// For JavaScript calls, determine whether the target has an arity match
// and whether it has a sloppy receiver.
- if (target->IsJSFunction()) {
- Handle<JSFunction> function = Handle<JSFunction>::cast(target);
+ if (callable->IsJSFunction()) {
+ Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
SharedFunctionInfo shared = function->shared();
// Check for math intrinsics.
@@ -6004,7 +6151,9 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> target,
wasm::FunctionSig* sig = wasm::WasmOpcodes::Signature(wasm::kExpr##name); \
if (!sig) sig = wasm::WasmOpcodes::AsmjsSignature(wasm::kExpr##name); \
DCHECK_NOT_NULL(sig); \
- if (*expected_sig == *sig) return WasmImportCallKind::k##name; \
+ if (*expected_sig == *sig) { \
+ return std::make_pair(WasmImportCallKind::k##name, callable); \
+ } \
}
#define COMPARE_SIG_FOR_BUILTIN_F64(name) \
case Builtins::kMath##name: \
@@ -6051,19 +6200,23 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> target,
if (IsClassConstructor(shared.kind())) {
// Class constructor will throw anyway.
- return WasmImportCallKind::kUseCallBuiltin;
+ return std::make_pair(WasmImportCallKind::kUseCallBuiltin, callable);
}
bool sloppy = is_sloppy(shared.language_mode()) && !shared.native();
if (shared.internal_formal_parameter_count() ==
expected_sig->parameter_count()) {
- return sloppy ? WasmImportCallKind::kJSFunctionArityMatchSloppy
- : WasmImportCallKind::kJSFunctionArityMatch;
+ return std::make_pair(
+ sloppy ? WasmImportCallKind::kJSFunctionArityMatchSloppy
+ : WasmImportCallKind::kJSFunctionArityMatch,
+ callable);
}
- return sloppy ? WasmImportCallKind::kJSFunctionArityMismatchSloppy
- : WasmImportCallKind::kJSFunctionArityMismatch;
+ return std::make_pair(
+ sloppy ? WasmImportCallKind::kJSFunctionArityMismatchSloppy
+ : WasmImportCallKind::kJSFunctionArityMismatch,
+ callable);
}
// Unknown case. Use the call builtin.
- return WasmImportCallKind::kUseCallBuiltin;
+ return std::make_pair(WasmImportCallKind::kUseCallBuiltin, callable);
}
wasm::WasmOpcode GetMathIntrinsicOpcode(WasmImportCallKind kind,
@@ -6103,10 +6256,9 @@ wasm::WasmOpcode GetMathIntrinsicOpcode(WasmImportCallKind kind,
#undef CASE
}
-wasm::WasmCode* CompileWasmMathIntrinsic(wasm::WasmEngine* wasm_engine,
- wasm::NativeModule* native_module,
- WasmImportCallKind kind,
- wasm::FunctionSig* sig) {
+wasm::WasmCompilationResult CompileWasmMathIntrinsic(
+ wasm::WasmEngine* wasm_engine, WasmImportCallKind kind,
+ wasm::FunctionSig* sig) {
DCHECK_EQ(1, sig->return_count());
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"),
@@ -6125,7 +6277,7 @@ wasm::WasmCode* CompileWasmMathIntrinsic(wasm::WasmEngine* wasm_engine,
InstructionSelector::AlignmentRequirements()));
wasm::CompilationEnv env(
- native_module->module(), wasm::UseTrapHandler::kNoTrapHandler,
+ nullptr, wasm::UseTrapHandler::kNoTrapHandler,
wasm::RuntimeExceptionSupport::kNoRuntimeExceptionSupport,
wasm::kAllWasmFeatures, wasm::LowerSimd::kNoLowerSimd);
@@ -6167,21 +6319,12 @@ wasm::WasmCode* CompileWasmMathIntrinsic(wasm::WasmEngine* wasm_engine,
wasm_engine, call_descriptor, mcgraph, Code::WASM_FUNCTION,
wasm::WasmCode::kFunction, debug_name, WasmStubAssemblerOptions(),
source_positions);
- std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
- wasm::WasmCode::kAnonymousFuncIndex, result.code_desc,
- result.frame_slot_count, result.tagged_parameter_slots,
- std::move(result.protected_instructions),
- std::move(result.source_positions), wasm::WasmCode::kFunction,
- wasm::ExecutionTier::kNone);
- // TODO(titzer): add counters for math intrinsic code size / allocation
- return native_module->PublishCode(std::move(wasm_code));
+ return result;
}
-wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine* wasm_engine,
- wasm::NativeModule* native_module,
- WasmImportCallKind kind,
- wasm::FunctionSig* sig,
- bool source_positions) {
+wasm::WasmCompilationResult CompileWasmImportCallWrapper(
+ wasm::WasmEngine* wasm_engine, wasm::CompilationEnv* env,
+ WasmImportCallKind kind, wasm::FunctionSig* sig, bool source_positions) {
DCHECK_NE(WasmImportCallKind::kLinkError, kind);
DCHECK_NE(WasmImportCallKind::kWasmToWasm, kind);
@@ -6189,7 +6332,7 @@ wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine* wasm_engine,
if (FLAG_wasm_math_intrinsics &&
kind >= WasmImportCallKind::kFirstMathIntrinsic &&
kind <= WasmImportCallKind::kLastMathIntrinsic) {
- return CompileWasmMathIntrinsic(wasm_engine, native_module, kind, sig);
+ return CompileWasmMathIntrinsic(wasm_engine, kind, sig);
}
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"),
@@ -6214,7 +6357,7 @@ wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine* wasm_engine,
WasmWrapperGraphBuilder builder(&zone, &jsgraph, sig, source_position_table,
StubCallMode::kCallWasmRuntimeStub,
- native_module->enabled_features());
+ env->enabled_features);
builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect);
builder.BuildWasmImportCallWrapper(kind);
@@ -6232,13 +6375,8 @@ wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine* wasm_engine,
wasm_engine, incoming, &jsgraph, Code::WASM_TO_JS_FUNCTION,
wasm::WasmCode::kWasmToJsWrapper, func_name, WasmStubAssemblerOptions(),
source_position_table);
- std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
- wasm::WasmCode::kAnonymousFuncIndex, result.code_desc,
- result.frame_slot_count, result.tagged_parameter_slots,
- std::move(result.protected_instructions),
- std::move(result.source_positions), wasm::WasmCode::kWasmToJsWrapper,
- wasm::ExecutionTier::kNone);
- return native_module->PublishCode(std::move(wasm_code));
+ result.kind = wasm::WasmCompilationResult::kWasmToJsWrapper;
+ return result;
}
wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
@@ -6290,9 +6428,8 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
wasm::WasmCode::kWasmToCapiWrapper, debug_name,
WasmStubAssemblerOptions(), source_positions);
std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
- wasm::WasmCode::kAnonymousFuncIndex, result.code_desc,
- result.frame_slot_count, result.tagged_parameter_slots,
- std::move(result.protected_instructions),
+ wasm::kAnonymousFuncIndex, result.code_desc, result.frame_slot_count,
+ result.tagged_parameter_slots, std::move(result.protected_instructions),
std::move(result.source_positions), wasm::WasmCode::kWasmToCapiWrapper,
wasm::ExecutionTier::kNone);
return native_module->PublishCode(std::move(wasm_code));
@@ -6338,24 +6475,26 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry(
wasm::WasmCode::kInterpreterEntry, func_name.begin(),
WasmStubAssemblerOptions());
result.result_tier = wasm::ExecutionTier::kInterpreter;
+ result.kind = wasm::WasmCompilationResult::kInterpreterEntry;
return result;
}
MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
- Zone zone(isolate->allocator(), ZONE_NAME);
- Graph graph(&zone);
- CommonOperatorBuilder common(&zone);
+ std::unique_ptr<Zone> zone =
+ base::make_unique<Zone>(isolate->allocator(), ZONE_NAME);
+ Graph* graph = new (zone.get()) Graph(zone.get());
+ CommonOperatorBuilder common(zone.get());
MachineOperatorBuilder machine(
- &zone, MachineType::PointerRepresentation(),
+ zone.get(), MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
- JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
+ JSGraph jsgraph(isolate, graph, &common, nullptr, nullptr, &machine);
Node* control = nullptr;
Node* effect = nullptr;
- WasmWrapperGraphBuilder builder(&zone, &jsgraph, sig, nullptr,
+ WasmWrapperGraphBuilder builder(zone.get(), &jsgraph, sig, nullptr,
StubCallMode::kCallCodeObject,
wasm::WasmFeaturesFromIsolate(isolate));
builder.set_control_ptr(&control);
@@ -6363,29 +6502,36 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
builder.BuildCWasmEntry();
// Schedule and compile to machine code.
- CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
- &zone, false, CWasmEntryParameters::kNumParameters + 1,
- CallDescriptor::kNoFlags);
+ MachineType sig_types[] = {MachineType::Pointer(), // return
+ MachineType::Pointer(), // target
+ MachineType::AnyTagged(), // object_ref
+ MachineType::Pointer(), // argv
+ MachineType::Pointer()}; // c_entry_fp
+ MachineSignature incoming_sig(1, 4, sig_types);
+ // Traps need the root register, for TailCallRuntimeWithCEntry to call
+ // Runtime::kThrowWasmError.
+ bool initialize_root_flag = true;
+ CallDescriptor* incoming = Linkage::GetSimplifiedCDescriptor(
+ zone.get(), &incoming_sig, initialize_root_flag);
// Build a name in the form "c-wasm-entry:<params>:<returns>".
static constexpr size_t kMaxNameLen = 128;
- char debug_name[kMaxNameLen] = "c-wasm-entry:";
- AppendSignature(debug_name, kMaxNameLen, sig);
-
- MaybeHandle<Code> maybe_code = Pipeline::GenerateCodeForWasmHeapStub(
- isolate, incoming, &graph, Code::C_WASM_ENTRY, debug_name,
- AssemblerOptions::Default(isolate));
- Handle<Code> code;
- if (!maybe_code.ToHandle(&code)) {
- return maybe_code;
- }
-#ifdef ENABLE_DISASSEMBLER
- if (FLAG_print_opt_code) {
- CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
- OFStream os(tracing_scope.file());
- code->Disassemble(debug_name, os);
- }
-#endif
+ auto debug_name = std::unique_ptr<char[]>(new char[kMaxNameLen]);
+ memcpy(debug_name.get(), "c-wasm-entry:", 14);
+ AppendSignature(debug_name.get(), kMaxNameLen, sig);
+
+ // Run the compilation job synchronously.
+ std::unique_ptr<OptimizedCompilationJob> job(
+ Pipeline::NewWasmHeapStubCompilationJob(
+ isolate, incoming, std::move(zone), graph, Code::C_WASM_ENTRY,
+ std::move(debug_name), AssemblerOptions::Default(isolate)));
+
+ if (job->PrepareJob(isolate) == CompilationJob::FAILED ||
+ job->ExecuteJob() == CompilationJob::FAILED ||
+ job->FinalizeJob(isolate) == CompilationJob::FAILED) {
+ return {};
+ }
+ Handle<Code> code = job->compilation_info()->code();
return code;
}