Commit 117a56b7 authored by gdeepti's avatar gdeepti Committed by Commit bot

Add new relocation type WASM_MEMORY_SIZE_REFERENCE, use relocatable pointers...

Add new relocation type WASM_MEMORY_SIZE_REFERENCE, use relocatable pointers to update wasm memory size references in generated code.
 - Add new RelocInfo mode WASM_MEMORY_SIZE_REFERENCE in the assembler and add relocation information to immediates in compare instructions.
 - Use relocatable constants for MemSize/BoundsCheck in the wasm compiler

R=titzer@chromium.org, yangguo@chromium.org, bradnelson@chromium.org

Review-Url: https://codereview.chromium.org/1921203002
Cr-Commit-Position: refs/heads/master@{#36044}
parent 9f214787
...@@ -71,11 +71,6 @@ Address RelocInfo::target_address() { ...@@ -71,11 +71,6 @@ Address RelocInfo::target_address() {
return Assembler::target_address_at(pc_, host_); return Assembler::target_address_at(pc_, host_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT || rmode_ == EMBEDDED_OBJECT
...@@ -118,19 +113,6 @@ void RelocInfo::set_target_address(Address target, ...@@ -118,19 +113,6 @@ void RelocInfo::set_target_address(Address target,
} }
} }
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_));
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
Address updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Assembler::set_target_address_at(isolate_, pc_, host_, updated_reference,
icache_flush_mode);
}
Object* RelocInfo::target_object() { Object* RelocInfo::target_object() {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
......
...@@ -255,6 +255,42 @@ bool RelocInfo::IsInConstantPool() { ...@@ -255,6 +255,42 @@ bool RelocInfo::IsInConstantPool() {
return Assembler::is_constant_pool_load(pc_); return Assembler::is_constant_pool_load(pc_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
uint32_t RelocInfo::wasm_memory_size_reference() {
DCHECK(IsWasmMemorySizeReference(rmode_));
return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_));
}
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
if (IsWasmMemoryReference(rmode_)) {
Address updated_memory_reference;
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
updated_memory_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_memory_reference &&
updated_memory_reference < new_base + new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, updated_memory_reference, icache_flush_mode);
} else if (IsWasmMemorySizeReference(rmode_)) {
uint32_t updated_size_reference;
DCHECK(wasm_memory_size_reference() <= old_size);
updated_size_reference =
new_size + (wasm_memory_size_reference() - old_size);
DCHECK(updated_size_reference <= new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, reinterpret_cast<Address>(updated_size_reference),
icache_flush_mode);
} else {
UNREACHABLE();
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of Operand and MemOperand // Implementation of Operand and MemOperand
......
...@@ -41,19 +41,6 @@ void RelocInfo::set_target_address(Address target, ...@@ -41,19 +41,6 @@ void RelocInfo::set_target_address(Address target,
} }
} }
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_));
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
Address updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Assembler::set_target_address_at(isolate_, pc_, host_, updated_reference,
icache_flush_mode);
}
inline int CPURegister::code() const { inline int CPURegister::code() const {
DCHECK(IsValid()); DCHECK(IsValid());
return reg_code; return reg_code;
...@@ -705,11 +692,6 @@ Address RelocInfo::target_address() { ...@@ -705,11 +692,6 @@ Address RelocInfo::target_address() {
return Assembler::target_address_at(pc_, host_); return Assembler::target_address_at(pc_, host_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT || rmode_ == EMBEDDED_OBJECT
......
...@@ -192,6 +192,41 @@ bool RelocInfo::IsInConstantPool() { ...@@ -192,6 +192,41 @@ bool RelocInfo::IsInConstantPool() {
return instr->IsLdrLiteralX(); return instr->IsLdrLiteralX();
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Memory::Address_at(Assembler::target_pointer_address_at(pc_));
}
uint32_t RelocInfo::wasm_memory_size_reference() {
DCHECK(IsWasmMemorySizeReference(rmode_));
return Memory::uint32_at(Assembler::target_pointer_address_at(pc_));
}
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
if (IsWasmMemoryReference(rmode_) && old_base != new_base) {
Address updated_memory_reference;
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
updated_memory_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_memory_reference &&
updated_memory_reference < new_base + new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, updated_memory_reference, icache_flush_mode);
} else if (IsWasmMemorySizeReference(rmode_)) {
uint32_t updated_size_reference;
DCHECK(wasm_memory_size_reference() <= old_size);
updated_size_reference =
new_size + (wasm_memory_size_reference() - old_size);
DCHECK(updated_size_reference <= new_size);
Memory::uint32_at(Assembler::target_pointer_address_at(pc_)) =
updated_size_reference;
} else {
UNREACHABLE();
}
}
Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2, Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2,
Register reg3, Register reg4) { Register reg3, Register reg4) {
......
...@@ -846,6 +846,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) { ...@@ -846,6 +846,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
return "generator continuation"; return "generator continuation";
case WASM_MEMORY_REFERENCE: case WASM_MEMORY_REFERENCE:
return "wasm memory reference"; return "wasm memory reference";
case WASM_MEMORY_SIZE_REFERENCE:
return "wasm memory size reference";
case NUMBER_OF_MODES: case NUMBER_OF_MODES:
case PC_JUMP: case PC_JUMP:
UNREACHABLE(); UNREACHABLE();
...@@ -941,6 +943,7 @@ void RelocInfo::Verify(Isolate* isolate) { ...@@ -941,6 +943,7 @@ void RelocInfo::Verify(Isolate* isolate) {
case DEBUG_BREAK_SLOT_AT_TAIL_CALL: case DEBUG_BREAK_SLOT_AT_TAIL_CALL:
case GENERATOR_CONTINUATION: case GENERATOR_CONTINUATION:
case WASM_MEMORY_REFERENCE: case WASM_MEMORY_REFERENCE:
case WASM_MEMORY_SIZE_REFERENCE:
case NONE32: case NONE32:
case NONE64: case NONE64:
break; break;
......
...@@ -384,9 +384,10 @@ class RelocInfo { ...@@ -384,9 +384,10 @@ class RelocInfo {
CODE_TARGET_WITH_ID, CODE_TARGET_WITH_ID,
DEBUGGER_STATEMENT, // Code target for the debugger statement. DEBUGGER_STATEMENT, // Code target for the debugger statement.
EMBEDDED_OBJECT, EMBEDDED_OBJECT,
CELL,
// To relocate pointers into the wasm memory embedded in wasm code // To relocate pointers into the wasm memory embedded in wasm code
WASM_MEMORY_REFERENCE, WASM_MEMORY_REFERENCE,
WASM_MEMORY_SIZE_REFERENCE,
CELL,
// Everything after runtime_entry (inclusive) is not GC'ed. // Everything after runtime_entry (inclusive) is not GC'ed.
RUNTIME_ENTRY, RUNTIME_ENTRY,
...@@ -430,7 +431,7 @@ class RelocInfo { ...@@ -430,7 +431,7 @@ class RelocInfo {
FIRST_REAL_RELOC_MODE = CODE_TARGET, FIRST_REAL_RELOC_MODE = CODE_TARGET,
LAST_REAL_RELOC_MODE = VENEER_POOL, LAST_REAL_RELOC_MODE = VENEER_POOL,
LAST_CODE_ENUM = DEBUGGER_STATEMENT, LAST_CODE_ENUM = DEBUGGER_STATEMENT,
LAST_GCED_ENUM = WASM_MEMORY_REFERENCE, LAST_GCED_ENUM = WASM_MEMORY_SIZE_REFERENCE,
FIRST_SHAREABLE_RELOC_MODE = CELL, FIRST_SHAREABLE_RELOC_MODE = CELL,
}; };
...@@ -521,6 +522,9 @@ class RelocInfo { ...@@ -521,6 +522,9 @@ class RelocInfo {
static inline bool IsWasmMemoryReference(Mode mode) { static inline bool IsWasmMemoryReference(Mode mode) {
return mode == WASM_MEMORY_REFERENCE; return mode == WASM_MEMORY_REFERENCE;
} }
static inline bool IsWasmMemorySizeReference(Mode mode) {
return mode == WASM_MEMORY_SIZE_REFERENCE;
}
static inline int ModeMask(Mode mode) { return 1 << mode; } static inline int ModeMask(Mode mode) { return 1 << mode; }
// Accessors // Accessors
...@@ -547,6 +551,12 @@ class RelocInfo { ...@@ -547,6 +551,12 @@ class RelocInfo {
// constant pool, otherwise the pointer is embedded in the instruction stream. // constant pool, otherwise the pointer is embedded in the instruction stream.
bool IsInConstantPool(); bool IsInConstantPool();
Address wasm_memory_reference();
uint32_t wasm_memory_size_reference();
void update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode = SKIP_ICACHE_FLUSH);
// this relocation applies to; // this relocation applies to;
// can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
INLINE(Address target_address()); INLINE(Address target_address());
...@@ -581,10 +591,6 @@ class RelocInfo { ...@@ -581,10 +591,6 @@ class RelocInfo {
ICacheFlushMode icache_flush_mode = ICacheFlushMode icache_flush_mode =
FLUSH_ICACHE_IF_NEEDED)); FLUSH_ICACHE_IF_NEEDED));
INLINE(Address wasm_memory_reference());
INLINE(void update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode = SKIP_ICACHE_FLUSH));
// Returns the address of the constant pool entry where the target address // Returns the address of the constant pool entry where the target address
// is held. This should only be called if IsInConstantPool returns true. // is held. This should only be called if IsInConstantPool returns true.
INLINE(Address constant_pool_entry_address()); INLINE(Address constant_pool_entry_address());
......
...@@ -1520,7 +1520,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, ...@@ -1520,7 +1520,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
destination->IsRegister() ? g.ToRegister(destination) : kScratchReg; destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
switch (src.type()) { switch (src.type()) {
case Constant::kInt32: case Constant::kInt32:
if (src.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) { if (src.rmode() == RelocInfo::WASM_MEMORY_REFERENCE ||
src.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE) {
__ mov(dst, Operand(src.ToInt32(), src.rmode())); __ mov(dst, Operand(src.ToInt32(), src.rmode()));
} else { } else {
__ mov(dst, Operand(src.ToInt32())); __ mov(dst, Operand(src.ToInt32()));
......
...@@ -201,11 +201,16 @@ class Arm64OperandConverter final : public InstructionOperandConverter { ...@@ -201,11 +201,16 @@ class Arm64OperandConverter final : public InstructionOperandConverter {
Constant constant = ToConstant(operand); Constant constant = ToConstant(operand);
switch (constant.type()) { switch (constant.type()) {
case Constant::kInt32: case Constant::kInt32:
return Operand(constant.ToInt32()); if (constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE) {
return Operand(constant.ToInt32(), constant.rmode());
} else {
return Operand(constant.ToInt32());
}
case Constant::kInt64: case Constant::kInt64:
if (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) { if (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) {
return Operand(constant.ToInt64(), constant.rmode()); return Operand(constant.ToInt64(), constant.rmode());
} else { } else {
DCHECK(constant.rmode() != RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
return Operand(constant.ToInt64()); return Operand(constant.ToInt64());
} }
case Constant::kFloat32: case Constant::kFloat32:
......
...@@ -149,7 +149,8 @@ std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) { ...@@ -149,7 +149,8 @@ std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
bool operator==(RelocatablePtrConstantInfo const& lhs, bool operator==(RelocatablePtrConstantInfo const& lhs,
RelocatablePtrConstantInfo const& rhs) { RelocatablePtrConstantInfo const& rhs) {
return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value(); return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() &&
lhs.type() == rhs.type();
} }
bool operator!=(RelocatablePtrConstantInfo const& lhs, bool operator!=(RelocatablePtrConstantInfo const& lhs,
...@@ -158,12 +159,12 @@ bool operator!=(RelocatablePtrConstantInfo const& lhs, ...@@ -158,12 +159,12 @@ bool operator!=(RelocatablePtrConstantInfo const& lhs,
} }
size_t hash_value(RelocatablePtrConstantInfo const& p) { size_t hash_value(RelocatablePtrConstantInfo const& p) {
return base::hash_combine(p.value(), p.rmode()); return base::hash_combine(p.value(), p.rmode(), p.type());
} }
std::ostream& operator<<(std::ostream& os, std::ostream& operator<<(std::ostream& os,
RelocatablePtrConstantInfo const& p) { RelocatablePtrConstantInfo const& p) {
return os << p.value() << "|" << p.rmode(); return os << p.value() << "|" << p.rmode() << "|" << p.type();
} }
#define CACHED_OP_LIST(V) \ #define CACHED_OP_LIST(V) \
...@@ -703,12 +704,11 @@ const Operator* CommonOperatorBuilder::RelocatableInt32Constant( ...@@ -703,12 +704,11 @@ const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
const Operator* CommonOperatorBuilder::RelocatableInt64Constant( const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
int64_t value, RelocInfo::Mode rmode) { int64_t value, RelocInfo::Mode rmode) {
return new (zone()) Operator1<RelocatablePtrConstantInfo>( // -- return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode
"RelocatableInt64Constant", // name "RelocatableInt64Constant", // name
0, 0, 0, 1, 0, 0, // counts 0, 0, 0, 1, 0, 0, // counts
RelocatablePtrConstantInfo(static_cast<intptr_t>(value), // parameter RelocatablePtrConstantInfo(value, rmode)); // parameter
rmode));
} }
const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep, const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
......
...@@ -117,15 +117,21 @@ const ParameterInfo& ParameterInfoOf(const Operator* const); ...@@ -117,15 +117,21 @@ const ParameterInfo& ParameterInfoOf(const Operator* const);
class RelocatablePtrConstantInfo final { class RelocatablePtrConstantInfo final {
public: public:
RelocatablePtrConstantInfo(intptr_t value, RelocInfo::Mode rmode) enum Type { kInt32, kInt64 };
: value_(value), rmode_(rmode) {}
RelocatablePtrConstantInfo(int32_t value, RelocInfo::Mode rmode)
: value_(value), rmode_(rmode), type_(kInt32) {}
RelocatablePtrConstantInfo(int64_t value, RelocInfo::Mode rmode)
: value_(value), rmode_(rmode), type_(kInt64) {}
intptr_t value() const { return value_; } intptr_t value() const { return value_; }
RelocInfo::Mode rmode() const { return rmode_; } RelocInfo::Mode rmode() const { return rmode_; }
Type type() const { return type_; }
private: private:
intptr_t value_; intptr_t value_;
RelocInfo::Mode rmode_; RelocInfo::Mode rmode_;
Type type_;
}; };
bool operator==(RelocatablePtrConstantInfo const& lhs, bool operator==(RelocatablePtrConstantInfo const& lhs,
......
...@@ -66,7 +66,8 @@ class IA32OperandConverter : public InstructionOperandConverter { ...@@ -66,7 +66,8 @@ class IA32OperandConverter : public InstructionOperandConverter {
Immediate ToImmediate(InstructionOperand* operand) { Immediate ToImmediate(InstructionOperand* operand) {
Constant constant = ToConstant(operand); Constant constant = ToConstant(operand);
if (constant.type() == Constant::kInt32 && if (constant.type() == Constant::kInt32 &&
constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) { (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE ||
constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE)) {
return Immediate(reinterpret_cast<Address>(constant.ToInt32()), return Immediate(reinterpret_cast<Address>(constant.ToInt32()),
constant.rmode()); constant.rmode());
} }
......
...@@ -504,14 +504,17 @@ std::ostream& operator<<(std::ostream& os, ...@@ -504,14 +504,17 @@ std::ostream& operator<<(std::ostream& os,
Constant::Constant(int32_t v) : type_(kInt32), value_(v) {} Constant::Constant(int32_t v) : type_(kInt32), value_(v) {}
Constant::Constant(RelocatablePtrConstantInfo info) Constant::Constant(RelocatablePtrConstantInfo info) {
#ifdef V8_HOST_ARCH_32_BIT if (info.type() == RelocatablePtrConstantInfo::kInt32) {
: type_(kInt32), value_(info.value()), rmode_(info.rmode()) { type_ = kInt32;
} } else if (info.type() == RelocatablePtrConstantInfo::kInt64) {
#else type_ = kInt64;
: type_(kInt64), value_(info.value()), rmode_(info.rmode()) { } else {
UNREACHABLE();
}
value_ = info.value();
rmode_ = info.rmode();
} }
#endif
Handle<HeapObject> Constant::ToHeapObject() const { Handle<HeapObject> Constant::ToHeapObject() const {
DCHECK_EQ(kHeapObject, type()); DCHECK_EQ(kHeapObject, type());
......
...@@ -1331,7 +1331,8 @@ class InstructionSequence final : public ZoneObject { ...@@ -1331,7 +1331,8 @@ class InstructionSequence final : public ZoneObject {
Immediates& immediates() { return immediates_; } Immediates& immediates() { return immediates_; }
ImmediateOperand AddImmediate(const Constant& constant) { ImmediateOperand AddImmediate(const Constant& constant) {
if (constant.type() == Constant::kInt32) { if (constant.type() == Constant::kInt32 &&
RelocInfo::IsNone(constant.rmode())) {
return ImmediateOperand(ImmediateOperand::INLINE, constant.ToInt32()); return ImmediateOperand(ImmediateOperand::INLINE, constant.ToInt32());
} }
int index = static_cast<int>(immediates_.size()); int index = static_cast<int>(immediates_.size());
......
...@@ -44,6 +44,10 @@ class X64OperandConverter : public InstructionOperandConverter { ...@@ -44,6 +44,10 @@ class X64OperandConverter : public InstructionOperandConverter {
DCHECK_EQ(0, bit_cast<int64_t>(constant.ToFloat64())); DCHECK_EQ(0, bit_cast<int64_t>(constant.ToFloat64()));
return Immediate(0); return Immediate(0);
} }
if (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE ||
constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE) {
return Immediate(constant.ToInt32(), constant.rmode());
}
return Immediate(constant.ToInt32()); return Immediate(constant.ToInt32());
} }
...@@ -2150,6 +2154,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, ...@@ -2150,6 +2154,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
if (src.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) { if (src.rmode() == RelocInfo::WASM_MEMORY_REFERENCE) {
__ movq(dst, src.ToInt64(), src.rmode()); __ movq(dst, src.ToInt64(), src.rmode());
} else { } else {
DCHECK(src.rmode() != RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
__ Set(dst, src.ToInt64()); __ Set(dst, src.ToInt64());
} }
break; break;
......
...@@ -81,11 +81,6 @@ Address RelocInfo::target_address() { ...@@ -81,11 +81,6 @@ Address RelocInfo::target_address() {
return Assembler::target_address_at(pc_, host_); return Assembler::target_address_at(pc_, host_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Memory::Address_at(pc_);
}
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT || rmode_ == EMBEDDED_OBJECT
...@@ -119,21 +114,6 @@ void RelocInfo::set_target_address(Address target, ...@@ -119,21 +114,6 @@ void RelocInfo::set_target_address(Address target,
} }
} }
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_));
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
Address updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Memory::Address_at(pc_) = updated_reference;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate_, pc_, sizeof(int32_t));
}
}
Object* RelocInfo::target_object() { Object* RelocInfo::target_object() {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return Memory::Object_at(pc_); return Memory::Object_at(pc_);
......
...@@ -186,6 +186,42 @@ bool RelocInfo::IsInConstantPool() { ...@@ -186,6 +186,42 @@ bool RelocInfo::IsInConstantPool() {
return false; return false;
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Memory::Address_at(pc_);
}
uint32_t RelocInfo::wasm_memory_size_reference() {
DCHECK(IsWasmMemorySizeReference(rmode_));
return Memory::uint32_at(pc_);
}
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
if (IsWasmMemoryReference(rmode_)) {
Address updated_reference;
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Memory::Address_at(pc_) = updated_reference;
} else if (IsWasmMemorySizeReference(rmode_)) {
uint32_t updated_size_reference;
DCHECK(wasm_memory_size_reference() <= old_size);
updated_size_reference =
new_size + (wasm_memory_size_reference() - old_size);
DCHECK(updated_size_reference <= new_size);
Memory::uint32_at(pc_) = updated_size_reference;
} else {
UNREACHABLE();
}
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate_, pc_, sizeof(int32_t));
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of Operand // Implementation of Operand
......
...@@ -102,11 +102,6 @@ Address RelocInfo::target_address() { ...@@ -102,11 +102,6 @@ Address RelocInfo::target_address() {
return Assembler::target_address_at(pc_, host_); return Assembler::target_address_at(pc_, host_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || DCHECK(IsCodeTarget(rmode_) ||
IsRuntimeEntry(rmode_) || IsRuntimeEntry(rmode_) ||
...@@ -156,19 +151,6 @@ void RelocInfo::set_target_address(Address target, ...@@ -156,19 +151,6 @@ void RelocInfo::set_target_address(Address target,
} }
} }
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_));
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
Address updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Assembler::set_target_address_at(isolate_, pc_, host_, updated_reference,
icache_flush_mode);
}
Address Assembler::target_address_from_return_address(Address pc) { Address Assembler::target_address_from_return_address(Address pc) {
return pc - kCallTargetAddressOffset; return pc - kCallTargetAddressOffset;
} }
......
...@@ -189,6 +189,42 @@ bool RelocInfo::IsInConstantPool() { ...@@ -189,6 +189,42 @@ bool RelocInfo::IsInConstantPool() {
return false; return false;
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
uint32_t RelocInfo::wasm_memory_size_reference() {
DCHECK(IsWasmMemorySizeReference(rmode_));
return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_));
}
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
if (IsWasmMemoryReference(rmode_)) {
Address updated_memory_reference;
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
updated_memory_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_memory_reference &&
updated_memory_reference < new_base + new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, updated_memory_reference, icache_flush_mode);
} else if (IsWasmMemorySizeReference(rmode_)) {
uint32_t updated_size_reference;
DCHECK(wasm_memory_size_reference() <= old_size);
updated_size_reference =
new_size + (wasm_memory_size_reference() - old_size);
DCHECK(updated_size_reference <= new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, reinterpret_cast<Address>(updated_size_reference),
icache_flush_mode);
} else {
UNREACHABLE();
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of Operand and MemOperand. // Implementation of Operand and MemOperand.
......
...@@ -102,11 +102,6 @@ Address RelocInfo::target_address() { ...@@ -102,11 +102,6 @@ Address RelocInfo::target_address() {
return Assembler::target_address_at(pc_, host_); return Assembler::target_address_at(pc_, host_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || DCHECK(IsCodeTarget(rmode_) ||
IsRuntimeEntry(rmode_) || IsRuntimeEntry(rmode_) ||
...@@ -158,19 +153,6 @@ void RelocInfo::set_target_address(Address target, ...@@ -158,19 +153,6 @@ void RelocInfo::set_target_address(Address target,
} }
} }
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_));
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
Address updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Assembler::set_target_address_at(isolate_, pc_, host_, updated_reference,
icache_flush_mode);
}
Address Assembler::target_address_from_return_address(Address pc) { Address Assembler::target_address_from_return_address(Address pc) {
return pc - kCallTargetAddressOffset; return pc - kCallTargetAddressOffset;
} }
......
...@@ -167,6 +167,43 @@ bool RelocInfo::IsInConstantPool() { ...@@ -167,6 +167,43 @@ bool RelocInfo::IsInConstantPool() {
return false; return false;
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Assembler::target_address_at(pc_, host_);
}
uint32_t RelocInfo::wasm_memory_size_reference() {
DCHECK(IsWasmMemorySizeReference(rmode_));
return static_cast<uint32_t>(
reinterpret_cast<intptr_t>((Assembler::target_address_at(pc_, host_))));
}
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
if (IsWasmMemoryReference(rmode_)) {
Address updated_memory_reference;
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
updated_memory_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_memory_reference &&
updated_memory_reference < new_base + new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, updated_memory_reference, icache_flush_mode);
} else if (IsWasmMemorySizeReference(rmode_)) {
uint32_t updated_size_reference;
DCHECK(wasm_memory_size_reference() <= old_size);
updated_size_reference =
new_size + (wasm_memory_size_reference() - old_size);
DCHECK(updated_size_reference <= new_size);
Assembler::set_target_address_at(
isolate_, pc_, host_, reinterpret_cast<Address>(updated_size_reference),
icache_flush_mode);
} else {
UNREACHABLE();
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of Operand and MemOperand. // Implementation of Operand and MemOperand.
......
...@@ -328,11 +328,6 @@ Address RelocInfo::target_address() { ...@@ -328,11 +328,6 @@ Address RelocInfo::target_address() {
return Assembler::target_address_at(pc_, host_); return Assembler::target_address_at(pc_, host_);
} }
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Memory::Address_at(pc_);
}
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT || rmode_ == EMBEDDED_OBJECT
...@@ -370,21 +365,6 @@ void RelocInfo::set_target_address(Address target, ...@@ -370,21 +365,6 @@ void RelocInfo::set_target_address(Address target,
} }
} }
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, size_t old_size, size_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_));
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
Address updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Memory::Address_at(pc_) = updated_reference;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate_, pc_, sizeof(int64_t));
}
}
Object* RelocInfo::target_object() { Object* RelocInfo::target_object() {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return Memory::Object_at(pc_); return Memory::Object_at(pc_);
......
...@@ -114,6 +114,45 @@ void CpuFeatures::PrintFeatures() { ...@@ -114,6 +114,45 @@ void CpuFeatures::PrintFeatures() {
CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM)); CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM));
} }
// -----------------------------------------------------------------------------
// Implementation of RelocInfo
Address RelocInfo::wasm_memory_reference() {
DCHECK(IsWasmMemoryReference(rmode_));
return Memory::Address_at(pc_);
}
uint32_t RelocInfo::wasm_memory_size_reference() {
DCHECK(IsWasmMemorySizeReference(rmode_));
return Memory::uint32_at(pc_);
}
void RelocInfo::update_wasm_memory_reference(
Address old_base, Address new_base, uint32_t old_size, uint32_t new_size,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsWasmMemoryReference(rmode_) || IsWasmMemorySizeReference(rmode_));
if (IsWasmMemoryReference(rmode_)) {
Address updated_reference;
DCHECK(old_base <= wasm_memory_reference() &&
wasm_memory_reference() < old_base + old_size);
updated_reference = new_base + (wasm_memory_reference() - old_base);
DCHECK(new_base <= updated_reference &&
updated_reference < new_base + new_size);
Memory::Address_at(pc_) = updated_reference;
} else if (IsWasmMemorySizeReference(rmode_)) {
uint32_t updated_size_reference;
DCHECK(wasm_memory_size_reference() <= old_size);
updated_size_reference =
new_size + (wasm_memory_size_reference() - old_size);
DCHECK(updated_size_reference <= new_size);
Memory::uint32_at(pc_) = updated_size_reference;
} else {
UNREACHABLE();
}
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate_, pc_, sizeof(int64_t));
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of Operand // Implementation of Operand
...@@ -563,14 +602,17 @@ void Assembler::immediate_arithmetic_op(byte subcode, ...@@ -563,14 +602,17 @@ void Assembler::immediate_arithmetic_op(byte subcode,
if (is_int8(src.value_)) { if (is_int8(src.value_)) {
emit(0x83); emit(0x83);
emit_modrm(subcode, dst); emit_modrm(subcode, dst);
if (!RelocInfo::IsNone(src.rmode_)) {
RecordRelocInfo(src.rmode_);
}
emit(src.value_); emit(src.value_);
} else if (dst.is(rax)) { } else if (dst.is(rax)) {
emit(0x05 | (subcode << 3)); emit(0x05 | (subcode << 3));
emitl(src.value_); emit(src);
} else { } else {
emit(0x81); emit(0x81);
emit_modrm(subcode, dst); emit_modrm(subcode, dst);
emitl(src.value_); emit(src);
} }
} }
...@@ -583,11 +625,14 @@ void Assembler::immediate_arithmetic_op(byte subcode, ...@@ -583,11 +625,14 @@ void Assembler::immediate_arithmetic_op(byte subcode,
if (is_int8(src.value_)) { if (is_int8(src.value_)) {
emit(0x83); emit(0x83);
emit_operand(subcode, dst); emit_operand(subcode, dst);
if (!RelocInfo::IsNone(src.rmode_)) {
RecordRelocInfo(src.rmode_);
}
emit(src.value_); emit(src.value_);
} else { } else {
emit(0x81); emit(0x81);
emit_operand(subcode, dst); emit_operand(subcode, dst);
emitl(src.value_); emit(src);
} }
} }
......
...@@ -334,6 +334,8 @@ enum RoundingMode { ...@@ -334,6 +334,8 @@ enum RoundingMode {
class Immediate BASE_EMBEDDED { class Immediate BASE_EMBEDDED {
public: public:
explicit Immediate(int32_t value) : value_(value) {} explicit Immediate(int32_t value) : value_(value) {}
explicit Immediate(int32_t value, RelocInfo::Mode rmode)
: value_(value), rmode_(rmode) {}
explicit Immediate(Smi* value) { explicit Immediate(Smi* value) {
DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI. DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value)); value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
...@@ -341,6 +343,7 @@ class Immediate BASE_EMBEDDED { ...@@ -341,6 +343,7 @@ class Immediate BASE_EMBEDDED {
private: private:
int32_t value_; int32_t value_;
RelocInfo::Mode rmode_ = RelocInfo::NONE32;
friend class Assembler; friend class Assembler;
}; };
...@@ -1758,7 +1761,12 @@ class Assembler : public AssemblerBase { ...@@ -1758,7 +1761,12 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode rmode, RelocInfo::Mode rmode,
TypeFeedbackId ast_id = TypeFeedbackId::None()); TypeFeedbackId ast_id = TypeFeedbackId::None());
inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode); inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
void emit(Immediate x) { emitl(x.value_); } void emit(Immediate x) {
if (!RelocInfo::IsNone(x.rmode_)) {
RecordRelocInfo(x.rmode_);
}
emitl(x.value_);
}
// Emits a REX prefix that encodes a 64-bit operand size and // Emits a REX prefix that encodes a 64-bit operand size and
// the top bit of both register codes. // the top bit of both register codes.
......
...@@ -18,14 +18,16 @@ using namespace v8::internal; ...@@ -18,14 +18,16 @@ using namespace v8::internal;
using namespace v8::internal::compiler; using namespace v8::internal::compiler;
static void UpdateMemoryReferences(Handle<Code> code, Address old_base, static void UpdateMemoryReferences(Handle<Code> code, Address old_base,
Address new_base, size_t old_size, Address new_base, uint32_t old_size,
size_t new_size) { uint32_t new_size) {
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
bool modified = false; bool modified = false;
int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE); int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode(); RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmMemoryReference(mode)) { if (RelocInfo::IsWasmMemoryReference(mode) ||
RelocInfo::IsWasmMemorySizeReference(mode)) {
// Patch addresses with change in memory start address // Patch addresses with change in memory start address
it.rinfo()->update_wasm_memory_reference(old_base, new_base, old_size, it.rinfo()->update_wasm_memory_reference(old_base, new_base, old_size,
new_size); new_size);
...@@ -143,3 +145,26 @@ TEST(RunLoadStoreRelocationOffset) { ...@@ -143,3 +145,26 @@ TEST(RunLoadStoreRelocationOffset) {
RunLoadStoreRelocationOffset<float>(MachineType::Float32()); RunLoadStoreRelocationOffset<float>(MachineType::Float32());
RunLoadStoreRelocationOffset<double>(MachineType::Float64()); RunLoadStoreRelocationOffset<double>(MachineType::Float64());
} }
TEST(Uint32LessThanRelocation) {
RawMachineAssemblerTester<uint32_t> m;
RawMachineLabel within_bounds, out_of_bounds;
Node* index = m.Int32Constant(0x200);
Node* limit =
m.RelocatableInt32Constant(0x200, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
Node* cond = m.AddNode(m.machine()->Uint32LessThan(), index, limit);
m.Branch(cond, &within_bounds, &out_of_bounds);
m.Bind(&within_bounds);
m.Return(m.Int32Constant(0xaced));
m.Bind(&out_of_bounds);
m.Return(m.Int32Constant(0xdeadbeef));
// Check that index is out of bounds with current size
CHECK_EQ(0xdeadbeef, m.Call());
m.GenerateCode();
Handle<Code> code = m.GetCode();
UpdateMemoryReferences(code, reinterpret_cast<Address>(1234),
reinterpret_cast<Address>(1234), 0x200, 0x400);
// Check that after limit is increased, index is within bounds.
CHECK_EQ(0xaced, m.Call());
}
...@@ -23,8 +23,7 @@ using namespace v8::internal::compiler; ...@@ -23,8 +23,7 @@ using namespace v8::internal::compiler;
static int32_t DummyStaticFunction(Object* result) { return 1; } static int32_t DummyStaticFunction(Object* result) { return 1; }
TEST(WasmRelocationArm) { TEST(WasmRelocationArmMemoryReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
v8::internal::byte buffer[4096]; v8::internal::byte buffer[4096];
...@@ -77,4 +76,59 @@ TEST(WasmRelocationArm) { ...@@ -77,4 +76,59 @@ TEST(WasmRelocationArm) {
#endif #endif
} }
TEST(WasmRelocationArmMemorySizeReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
v8::internal::byte buffer[4096];
DummyStaticFunction(NULL);
int32_t size = 512;
Label fail;
Assembler assm(isolate, buffer, sizeof buffer);
__ mov(r0, Operand(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
__ cmp(r0, Operand(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
__ b(ne, &fail);
__ mov(pc, Operand(lr));
__ bind(&fail);
__ mov(r0, Operand(0xdeadbeef));
__ mov(pc, Operand(lr));
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
CSignature0<int32_t> csig;
CodeRunner<int32_t> runnable(isolate, code, &csig);
int32_t ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef DEBUG
OFStream os(stdout);
code->Print(os);
::printf("f() = %d\n\n", ret_value);
#endif
size_t diff = 512;
int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmMemorySizeReference(mode)) {
it.rinfo()->update_wasm_memory_reference(
reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
it.rinfo()->wasm_memory_size_reference(),
it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
}
}
ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef DEBUG
code->Print(os);
::printf("f() = %d\n\n", ret_value);
#endif
}
#undef __ #undef __
...@@ -24,8 +24,7 @@ using namespace v8::internal::compiler; ...@@ -24,8 +24,7 @@ using namespace v8::internal::compiler;
static int64_t DummyStaticFunction(Object* result) { return 1; } static int64_t DummyStaticFunction(Object* result) { return 1; }
TEST(WasmRelocationArm64) { TEST(WasmRelocationArm64MemoryReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
v8::internal::byte buffer[4096]; v8::internal::byte buffer[4096];
...@@ -79,4 +78,61 @@ TEST(WasmRelocationArm64) { ...@@ -79,4 +78,61 @@ TEST(WasmRelocationArm64) {
#endif #endif
} }
TEST(WasmRelocationArm64MemorySizeReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
v8::internal::byte buffer[4096];
DummyStaticFunction(NULL);
Immediate size = Immediate(512, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
Label fail;
MacroAssembler masm(isolate, buffer, sizeof buffer,
v8::internal::CodeObjectRequired::kYes);
__ Mov(x0, size);
__ Cmp(x0, size);
__ B(ne, &fail);
__ Ret();
__ Bind(&fail);
__ Mov(x0, Immediate(0xdeadbeef));
__ Ret();
CodeDesc desc;
masm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
CSignature0<int64_t> csig;
CodeRunner<int64_t> runnable(isolate, code, &csig);
int64_t ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef DEBUG
OFStream os(stdout);
code->Print(os);
::printf("f() = %ld\n\n", ret_value);
#endif
int32_t diff = 512;
int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmMemorySizeReference(mode)) {
it.rinfo()->update_wasm_memory_reference(
reinterpret_cast<Address>(0x1234), reinterpret_cast<Address>(0x1234),
it.rinfo()->wasm_memory_size_reference(),
it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
}
}
ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef DEBUG
code->Print(os);
::printf("f() = %ld\n\n", ret_value);
#endif
}
#undef __ #undef __
...@@ -23,8 +23,7 @@ using namespace v8::internal::compiler; ...@@ -23,8 +23,7 @@ using namespace v8::internal::compiler;
static int32_t DummyStaticFunction(Object* result) { return 1; } static int32_t DummyStaticFunction(Object* result) { return 1; }
TEST(WasmRelocationIa32) { TEST(WasmRelocationIa32MemoryReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
Zone zone(isolate->allocator()); Zone zone(isolate->allocator());
HandleScope scope(isolate); HandleScope scope(isolate);
...@@ -78,7 +77,6 @@ TEST(WasmRelocationIa32) { ...@@ -78,7 +77,6 @@ TEST(WasmRelocationIa32) {
CHECK_EQ(ret_value, imm + offset); CHECK_EQ(ret_value, imm + offset);
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
// OFStream os(stdout);
code->Print(os); code->Print(os);
begin = code->instruction_start(); begin = code->instruction_start();
end = begin + code->instruction_size(); end = begin + code->instruction_size();
...@@ -86,4 +84,67 @@ TEST(WasmRelocationIa32) { ...@@ -86,4 +84,67 @@ TEST(WasmRelocationIa32) {
#endif #endif
} }
TEST(WasmRelocationIa32MemorySizeReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Zone zone(isolate->allocator());
HandleScope scope(isolate);
v8::internal::byte buffer[4096];
Assembler assm(isolate, buffer, sizeof buffer);
DummyStaticFunction(NULL);
int32_t size = 80;
Label fail;
__ mov(eax, Immediate(reinterpret_cast<Address>(size),
RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
__ cmp(eax, Immediate(reinterpret_cast<Address>(size),
RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
__ j(not_equal, &fail);
__ ret(0);
__ bind(&fail);
__ mov(eax, 0xdeadbeef);
__ ret(0);
CSignature0<int32_t> csig;
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
USE(code);
CodeRunner<int32_t> runnable(isolate, code, &csig);
int32_t ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef OBJECT_PRINT
OFStream os(stdout);
code->Print(os);
byte* begin = code->instruction_start();
byte* end = begin + code->instruction_size();
disasm::Disassembler::Disassemble(stdout, begin, end);
#endif
size_t offset = 10;
int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmMemorySizeReference(mode)) {
it.rinfo()->update_wasm_memory_reference(
reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
it.rinfo()->wasm_memory_size_reference(),
it.rinfo()->wasm_memory_size_reference() + offset, SKIP_ICACHE_FLUSH);
}
}
ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef OBJECT_PRINT
code->Print(os);
begin = code->instruction_start();
end = begin + code->instruction_size();
disasm::Disassembler::Disassemble(stdout, begin, end);
#endif
}
#undef __ #undef __
...@@ -22,8 +22,7 @@ using namespace v8::internal::compiler; ...@@ -22,8 +22,7 @@ using namespace v8::internal::compiler;
static int32_t DummyStaticFunction(Object* result) { return 1; } static int32_t DummyStaticFunction(Object* result) { return 1; }
TEST(WasmRelocationX64movq64) { TEST(WasmRelocationX64MemoryReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
v8::internal::byte buffer[4096]; v8::internal::byte buffer[4096];
...@@ -81,4 +80,63 @@ TEST(WasmRelocationX64movq64) { ...@@ -81,4 +80,63 @@ TEST(WasmRelocationX64movq64) {
#endif #endif
} }
TEST(WasmRelocationX64WasmMemorySizeReference) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
v8::internal::byte buffer[4096];
Assembler assm(isolate, buffer, sizeof buffer);
DummyStaticFunction(NULL);
int32_t size = 512;
Label fail;
__ movl(rax, Immediate(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
__ cmpl(rax, Immediate(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
__ j(not_equal, &fail);
__ ret(0);
__ bind(&fail);
__ movl(rax, Immediate(0xdeadbeef));
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
USE(code);
CSignature0<int64_t> csig;
CodeRunner<int64_t> runnable(isolate, code, &csig);
int64_t ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef OBJECT_PRINT
OFStream os(stdout);
code->Print(os);
byte* begin = code->instruction_start();
byte* end = begin + code->instruction_size();
disasm::Disassembler::Disassemble(stdout, begin, end);
#endif
int32_t diff = 512;
int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmMemorySizeReference(mode)) {
it.rinfo()->update_wasm_memory_reference(
reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
it.rinfo()->wasm_memory_size_reference(),
it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
}
}
ret_value = runnable.Call();
CHECK_NE(ret_value, 0xdeadbeef);
#ifdef OBJECT_PRINT
code->Print(os);
begin = code->instruction_start();
end = begin + code->instruction_size();
disasm::Disassembler::Disassemble(stdout, begin, end);
#endif
}
#undef __ #undef __
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