Commit ba864684 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Fix remaining external refs to take Address

Passing a pointer of the needed type, and then reading using
ReadUnalignedValue is pointless, since the compiler can assume
alignment of the pointer value.
This CL fixes the remaining external refs of wasm to take an Address to
a single buffer.

R=ahaas@chromium.org

Bug: v8:7570, v8:3770
Change-Id: If8a7324a4703e1e900cb3c5644baef207e6a371d
Reviewed-on: https://chromium-review.googlesource.com/1023406
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52754}
parent b49206de
......@@ -1719,13 +1719,12 @@ Node* WasmGraphBuilder::BuildBitCountingCall(Node* input, ExternalReference ref,
graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
input, *effect_, *control_);
MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 1);
sig_builder.AddReturn(MachineType::Int32());
sig_builder.AddParam(MachineType::Pointer());
MachineType sig_types[] = {MachineType::Int32(), MachineType::Pointer()};
MachineSignature sig(1, 1, sig_types);
Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
return BuildCCall(sig_builder.Build(), function, stack_slot_param);
return BuildCCall(&sig, function, stack_slot_param);
}
Node* WasmGraphBuilder::BuildI32Ctz(Node* input) {
......@@ -1845,52 +1844,37 @@ Node* WasmGraphBuilder::BuildCFuncInstruction(ExternalReference ref,
MachineType type, Node* input0,
Node* input1) {
// We do truncation by calling a C function which calculates the result.
// The input is passed to the C function as a double*'s to avoid double
// parameters. For this we reserve slots on the stack, store the parameters
// in those slots, pass pointers to the slot to the C function,
// and after calling the C function we collect the return value from
// the stack slot.
Node* stack_slot_param0 =
graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation()));
// The input is passed to the C function as a byte buffer holding the two
// input doubles. We reserve this byte buffer as a stack slot, store the
// parameters in this buffer slots, pass a pointer to the buffer to the C
// function, and after calling the C function we collect the return value from
// the buffer.
const int type_size = 1 << ElementSizeLog2Of(type.representation());
const int stack_slot_bytes = (input1 == nullptr ? 1 : 2) * type_size;
Node* stack_slot =
graph()->NewNode(jsgraph()->machine()->StackSlot(stack_slot_bytes));
const Operator* store_op0 = jsgraph()->machine()->Store(
const Operator* store_op = jsgraph()->machine()->Store(
StoreRepresentation(type.representation(), kNoWriteBarrier));
*effect_ = graph()->NewNode(store_op0, stack_slot_param0,
jsgraph()->Int32Constant(0), input0, *effect_,
*control_);
*effect_ = graph()->NewNode(store_op, stack_slot, jsgraph()->Int32Constant(0),
input0, *effect_, *control_);
Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
if (input1 == nullptr) {
const int input_count = 1;
Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0,
input_count);
sig_builder.AddParam(MachineType::Pointer());
BuildCCall(sig_builder.Build(), function, stack_slot_param0);
} else {
Node* stack_slot_param1 = graph()->NewNode(
jsgraph()->machine()->StackSlot(type.representation()));
const Operator* store_op1 = jsgraph()->machine()->Store(
StoreRepresentation(type.representation(), kNoWriteBarrier));
*effect_ = graph()->NewNode(store_op1, stack_slot_param1,
jsgraph()->Int32Constant(0), input1, *effect_,
*control_);
const int input_count = 2;
Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0,
input_count);
sig_builder.AddParam(MachineType::Pointer());
sig_builder.AddParam(MachineType::Pointer());
BuildCCall(sig_builder.Build(), function, stack_slot_param0,
stack_slot_param1);
if (input1 != nullptr) {
*effect_ = graph()->NewNode(store_op, stack_slot,
jsgraph()->Int32Constant(type_size), input1,
*effect_, *control_);
}
const Operator* load_op = jsgraph()->machine()->Load(type);
MachineType sig_types[] = {MachineType::Pointer()};
MachineSignature sig(0, 1, sig_types);
BuildCCall(&sig, function, stack_slot);
Node* load =
graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0),
*effect_, *control_);
const Operator* load_op = jsgraph()->machine()->Load(type);
Node* load = graph()->NewNode(
load_op, stack_slot, jsgraph()->Int32Constant(0), *effect_, *control_);
*effect_ = load;
return load;
}
......@@ -2493,37 +2477,31 @@ Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right,
Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right,
ExternalReference ref,
MachineType result_type, int trap_zero,
MachineType result_type,
wasm::TrapReason trap_zero,
wasm::WasmCodePosition position) {
Node* stack_slot_dst = graph()->NewNode(
jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
Node* stack_slot_src = graph()->NewNode(
jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
Node* stack_slot =
graph()->NewNode(jsgraph()->machine()->StackSlot(2 * sizeof(double)));
const Operator* store_op = jsgraph()->machine()->Store(
StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier));
*effect_ =
graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0),
left, *effect_, *control_);
*effect_ =
graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0),
right, *effect_, *control_);
*effect_ = graph()->NewNode(store_op, stack_slot, jsgraph()->Int32Constant(0),
left, *effect_, *control_);
*effect_ = graph()->NewNode(store_op, stack_slot,
jsgraph()->Int32Constant(sizeof(double)), right,
*effect_, *control_);
MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
sig_builder.AddReturn(MachineType::Int32());
sig_builder.AddParam(MachineType::Pointer());
sig_builder.AddParam(MachineType::Pointer());
MachineType sig_types[] = {MachineType::Int32(), MachineType::Pointer()};
MachineSignature sig(1, 1, sig_types);
Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
Node* call =
BuildCCall(sig_builder.Build(), function, stack_slot_dst, stack_slot_src);
Node* call = BuildCCall(&sig, function, stack_slot);
ZeroCheck32(static_cast<wasm::TrapReason>(trap_zero), call, position);
ZeroCheck32(trap_zero, call, position);
TrapIfEq32(wasm::kTrapDivUnrepresentable, call, -1, position);
const Operator* load_op = jsgraph()->machine()->Load(result_type);
Node* load =
graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0),
*effect_, *control_);
Node* load = graph()->NewNode(
load_op, stack_slot, jsgraph()->Int32Constant(0), *effect_, *control_);
*effect_ = load;
return load;
}
......@@ -3089,9 +3067,8 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<WeakCell> weak_instance,
args[pos++] = *control_;
// We only need a dummy call descriptor.
wasm::FunctionSig::Builder dummy_sig_builder(jsgraph()->zone(), 0, 0);
auto call_descriptor =
GetWasmCallDescriptor(jsgraph()->zone(), dummy_sig_builder.Build());
wasm::FunctionSig dummy_sig(0, 0, nullptr);
auto call_descriptor = GetWasmCallDescriptor(jsgraph()->zone(), &dummy_sig);
*effect_ =
graph()->NewNode(jsgraph()->common()->Call(call_descriptor), pos, args);
Return(jsgraph()->UndefinedConstant());
......@@ -3633,10 +3610,9 @@ Node* WasmGraphBuilder::BuildModifyThreadInWasmFlag(bool new_value) {
jsgraph()->isolate())
: ExternalReference::wasm_clear_thread_in_wasm_flag(
jsgraph()->isolate());
MachineSignature::Builder sig_builder(jsgraph()->zone(), 0, 0);
MachineSignature sig(0, 0, nullptr);
return BuildCCall(
sig_builder.Build(),
graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)));
&sig, graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)));
}
// Only call this function for code which is not reused across instantiations,
......
......@@ -441,7 +441,7 @@ class WasmGraphBuilder {
Node* BuildI64DivU(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI64RemU(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildDiv64Call(Node* left, Node* right, ExternalReference ref,
MachineType result_type, int trap_zero,
MachineType result_type, wasm::TrapReason trap_zero,
wasm::WasmCodePosition position);
Node* BuildJavaScriptToNumber(Node* node, Node* js_context);
......
......@@ -335,8 +335,9 @@ ExternalReference ExternalReference::wasm_word32_ror(Isolate* isolate) {
return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ror_wrapper)));
}
static void f64_acos_wrapper(double* param) {
WriteDoubleValue(param, base::ieee754::acos(ReadDoubleValue(param)));
static void f64_acos_wrapper(Address data) {
double input = ReadUnalignedValue<double>(data);
WriteUnalignedValue(data, base::ieee754::acos(input));
}
ExternalReference ExternalReference::f64_acos_wrapper_function(
......@@ -344,8 +345,9 @@ ExternalReference ExternalReference::f64_acos_wrapper_function(
return ExternalReference(Redirect(FUNCTION_ADDR(f64_acos_wrapper)));
}
static void f64_asin_wrapper(double* param) {
WriteDoubleValue(param, base::ieee754::asin(ReadDoubleValue(param)));
static void f64_asin_wrapper(Address data) {
double input = ReadUnalignedValue<double>(data);
WriteUnalignedValue<double>(data, base::ieee754::asin(input));
}
ExternalReference ExternalReference::f64_asin_wrapper_function(
......@@ -369,9 +371,10 @@ ExternalReference ExternalReference::wasm_clear_thread_in_wasm_flag(
Redirect(FUNCTION_ADDR(wasm::clear_thread_in_wasm_flag)));
}
static void f64_mod_wrapper(double* param0, double* param1) {
WriteDoubleValue(param0,
Modulo(ReadDoubleValue(param0), ReadDoubleValue(param1)));
static void f64_mod_wrapper(Address data) {
double dividend = ReadUnalignedValue<double>(data);
double divisor = ReadUnalignedValue<double>(data + sizeof(dividend));
WriteUnalignedValue<double>(data, Modulo(dividend, divisor));
}
ExternalReference ExternalReference::f64_mod_wrapper_function(
......
......@@ -1610,18 +1610,10 @@ static inline double ReadDoubleValue(Address p) {
return ReadUnalignedValue<double>(p);
}
inline double ReadDoubleValue(const double* address) {
return ReadUnalignedValue<double>(reinterpret_cast<Address>(address));
}
static inline void WriteDoubleValue(Address p, double value) {
WriteUnalignedValue(p, value);
}
inline void WriteDoubleValue(double* address, double value) {
WriteUnalignedValue(reinterpret_cast<Address>(address), value);
}
static inline uint16_t ReadUnalignedUInt16(Address p) {
return ReadUnalignedValue<uint16_t>(p);
}
......
......@@ -18,48 +18,37 @@ namespace v8 {
namespace internal {
namespace wasm {
namespace {
inline int64_t ReadUnalignedInt64(int64_t* address) {
return ReadUnalignedValue<int64_t>(reinterpret_cast<Address>(address));
void f32_trunc_wrapper(Address data) {
WriteUnalignedValue<float>(data, truncf(ReadUnalignedValue<float>(data)));
}
inline uint64_t ReadUnalignedUint64(uint64_t* address) {
return ReadUnalignedValue<uint64_t>(reinterpret_cast<Address>(address));
void f32_floor_wrapper(Address data) {
WriteUnalignedValue<float>(data, floorf(ReadUnalignedValue<float>(data)));
}
inline void WriteUnalignedInt64(int64_t* address, int64_t value) {
WriteUnalignedValue<int64_t>(reinterpret_cast<Address>(address), value);
void f32_ceil_wrapper(Address data) {
WriteUnalignedValue<float>(data, ceilf(ReadUnalignedValue<float>(data)));
}
inline void WriteUnalignedUint64(uint64_t* address, uint64_t value) {
WriteUnalignedValue<uint64_t>(reinterpret_cast<Address>(address), value);
void f32_nearest_int_wrapper(Address data) {
WriteUnalignedValue<float>(data, nearbyintf(ReadUnalignedValue<float>(data)));
}
} // namespace
void f32_trunc_wrapper(float* param) { *param = truncf(*param); }
void f32_floor_wrapper(float* param) { *param = floorf(*param); }
void f32_ceil_wrapper(float* param) { *param = ceilf(*param); }
void f32_nearest_int_wrapper(float* param) { *param = nearbyintf(*param); }
void f64_trunc_wrapper(double* param) {
WriteDoubleValue(param, trunc(ReadDoubleValue(param)));
void f64_trunc_wrapper(Address data) {
WriteUnalignedValue<double>(data, trunc(ReadUnalignedValue<double>(data)));
}
void f64_floor_wrapper(double* param) {
WriteDoubleValue(param, floor(ReadDoubleValue(param)));
void f64_floor_wrapper(Address data) {
WriteUnalignedValue<double>(data, floor(ReadUnalignedValue<double>(data)));
}
void f64_ceil_wrapper(double* param) {
WriteDoubleValue(param, ceil(ReadDoubleValue(param)));
void f64_ceil_wrapper(Address data) {
WriteUnalignedValue<double>(data, ceil(ReadUnalignedValue<double>(data)));
}
void f64_nearest_int_wrapper(double* param) {
WriteDoubleValue(param, nearbyint(ReadDoubleValue(param)));
void f64_nearest_int_wrapper(Address data) {
WriteUnalignedValue<double>(data,
nearbyint(ReadUnalignedValue<double>(data)));
}
void int64_to_float32_wrapper(Address data) {
......@@ -181,46 +170,46 @@ int32_t float64_to_uint64_wrapper(Address data) {
return 0;
}
int32_t int64_div_wrapper(int64_t* dst, int64_t* src) {
int64_t src_val = ReadUnalignedInt64(src);
int64_t dst_val = ReadUnalignedInt64(dst);
if (src_val == 0) {
int32_t int64_div_wrapper(Address data) {
int64_t dividend = ReadUnalignedValue<int64_t>(data);
int64_t divisor = ReadUnalignedValue<int64_t>(data + sizeof(dividend));
if (divisor == 0) {
return 0;
}
if (src_val == -1 && dst_val == std::numeric_limits<int64_t>::min()) {
if (divisor == -1 && dividend == std::numeric_limits<int64_t>::min()) {
return -1;
}
WriteUnalignedInt64(dst, dst_val / src_val);
WriteUnalignedValue<int64_t>(data, dividend / divisor);
return 1;
}
int32_t int64_mod_wrapper(int64_t* dst, int64_t* src) {
int64_t src_val = ReadUnalignedInt64(src);
int64_t dst_val = ReadUnalignedInt64(dst);
if (src_val == 0) {
int32_t int64_mod_wrapper(Address data) {
int64_t dividend = ReadUnalignedValue<int64_t>(data);
int64_t divisor = ReadUnalignedValue<int64_t>(data + sizeof(dividend));
if (divisor == 0) {
return 0;
}
WriteUnalignedInt64(dst, dst_val % src_val);
WriteUnalignedValue<int64_t>(data, dividend % divisor);
return 1;
}
int32_t uint64_div_wrapper(uint64_t* dst, uint64_t* src) {
uint64_t src_val = ReadUnalignedUint64(src);
uint64_t dst_val = ReadUnalignedUint64(dst);
if (src_val == 0) {
int32_t uint64_div_wrapper(Address data) {
uint64_t dividend = ReadUnalignedValue<uint64_t>(data);
uint64_t divisor = ReadUnalignedValue<uint64_t>(data + sizeof(dividend));
if (divisor == 0) {
return 0;
}
WriteUnalignedUint64(dst, dst_val / src_val);
WriteUnalignedValue<uint64_t>(data, dividend / divisor);
return 1;
}
int32_t uint64_mod_wrapper(uint64_t* dst, uint64_t* src) {
uint64_t src_val = ReadUnalignedUint64(src);
uint64_t dst_val = ReadUnalignedUint64(dst);
if (src_val == 0) {
int32_t uint64_mod_wrapper(Address data) {
uint64_t dividend = ReadUnalignedValue<uint64_t>(data);
uint64_t divisor = ReadUnalignedValue<uint64_t>(data + sizeof(dividend));
if (divisor == 0) {
return 0;
}
WriteUnalignedUint64(dst, dst_val % src_val);
WriteUnalignedValue<uint64_t>(data, dividend % divisor);
return 1;
}
......@@ -252,10 +241,10 @@ uint32_t word32_ror_wrapper(Address data) {
return (input >> shift) | (input << (32 - shift));
}
void float64_pow_wrapper(double* param0, double* param1) {
double x = ReadDoubleValue(param0);
double y = ReadDoubleValue(param1);
WriteDoubleValue(param0, Pow(x, y));
void float64_pow_wrapper(Address data) {
double x = ReadUnalignedValue<double>(data);
double y = ReadUnalignedValue<double>(data + sizeof(x));
WriteUnalignedValue<double>(data, Pow(x, y));
}
void set_thread_in_wasm_flag() { trap_handler::SetThreadInWasm(); }
......
......@@ -13,21 +13,21 @@ namespace v8 {
namespace internal {
namespace wasm {
void f32_trunc_wrapper(float* param);
void f32_trunc_wrapper(Address data);
void f32_floor_wrapper(float* param);
void f32_floor_wrapper(Address data);
void f32_ceil_wrapper(float* param);
void f32_ceil_wrapper(Address data);
void f32_nearest_int_wrapper(float* param);
void f32_nearest_int_wrapper(Address data);
void f64_trunc_wrapper(double* param);
void f64_trunc_wrapper(Address data);
void f64_floor_wrapper(double* param);
void f64_floor_wrapper(Address data);
void f64_ceil_wrapper(double* param);
void f64_ceil_wrapper(Address data);
void f64_nearest_int_wrapper(double* param);
void f64_nearest_int_wrapper(Address data);
void int64_to_float32_wrapper(Address data);
......@@ -45,13 +45,13 @@ int32_t float64_to_int64_wrapper(Address data);
int32_t float64_to_uint64_wrapper(Address data);
int32_t int64_div_wrapper(int64_t* dst, int64_t* src);
int32_t int64_div_wrapper(Address data);
int32_t int64_mod_wrapper(int64_t* dst, int64_t* src);
int32_t int64_mod_wrapper(Address data);
int32_t uint64_div_wrapper(uint64_t* dst, uint64_t* src);
int32_t uint64_div_wrapper(Address data);
int32_t uint64_mod_wrapper(uint64_t* dst, uint64_t* src);
int32_t uint64_mod_wrapper(Address data);
uint32_t word32_ctz_wrapper(Address data);
......@@ -65,7 +65,7 @@ uint32_t word32_rol_wrapper(Address data);
uint32_t word32_ror_wrapper(Address data);
void float64_pow_wrapper(double* param0, double* param1);
void float64_pow_wrapper(Address data);
void set_thread_in_wasm_flag();
void clear_thread_in_wasm_flag();
......
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