Commit fdb067dc authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

[wasm] JIT using WasmCodeManager: codegen components.

This CL introduces those codegen changes necessary for JIT-ing using
the WasmCodeManager.

Bug: v8:6876
Change-Id: I6b463b3e278f5e53f8dfa488f76eeaeb5231dbea
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/782261Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49554}
parent ed9b2072
......@@ -67,14 +67,13 @@ void RelocInfo::apply(intptr_t delta) {
Address RelocInfo::target_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE);
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
if (Assembler::IsMovW(Memory::int32_at(pc_))) {
return reinterpret_cast<Address>(pc_);
} else {
......
......@@ -357,6 +357,17 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
reinterpret_cast<Address>(size), flush_mode);
}
void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
set_embedded_address(isolate, address, icache_flush_mode);
}
Address RelocInfo::js_to_wasm_address() const {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
return embedded_address();
}
// -----------------------------------------------------------------------------
// Implementation of Operand and MemOperand
// See assembler-arm-inl.h for inlined constructors
......
......@@ -629,14 +629,13 @@ int RelocInfo::target_address_size() {
Address RelocInfo::target_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE);
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
return Assembler::target_pointer_address_at(pc_);
}
......
......@@ -195,6 +195,17 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
// No icache flushing needed, see comment in set_target_address_at.
}
void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
set_embedded_address(isolate, address, icache_flush_mode);
}
Address RelocInfo::js_to_wasm_address() const {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
return embedded_address();
}
bool AreAliased(const CPURegister& reg1, const CPURegister& reg2,
const CPURegister& reg3, const CPURegister& reg4,
const CPURegister& reg5, const CPURegister& reg6,
......
......@@ -658,6 +658,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
return "global handle";
case WASM_CALL:
return "internal wasm call";
case JS_TO_WASM_CALL:
return "js to wasm call";
case NUMBER_OF_MODES:
case PC_JUMP:
UNREACHABLE();
......@@ -740,6 +742,7 @@ void RelocInfo::Verify(Isolate* isolate) {
case WASM_FUNCTION_TABLE_SIZE_REFERENCE:
case WASM_GLOBAL_HANDLE:
case WASM_CALL:
case JS_TO_WASM_CALL:
case NONE32:
case NONE64:
break;
......
......@@ -367,6 +367,7 @@ class RelocInfo {
WASM_FUNCTION_TABLE_SIZE_REFERENCE,
WASM_GLOBAL_HANDLE,
WASM_CALL,
JS_TO_WASM_CALL,
RUNTIME_ENTRY,
COMMENT,
......@@ -470,7 +471,8 @@ class RelocInfo {
return IsWasmFunctionTableSizeReference(mode);
}
static inline bool IsWasmPtrReference(Mode mode) {
return mode == WASM_CONTEXT_REFERENCE || mode == WASM_GLOBAL_HANDLE;
return mode == WASM_CONTEXT_REFERENCE || mode == WASM_GLOBAL_HANDLE ||
mode == WASM_CALL || mode == JS_TO_WASM_CALL;
}
static inline int ModeMask(Mode mode) { return 1 << mode; }
......@@ -500,6 +502,7 @@ class RelocInfo {
Address wasm_context_reference() const;
uint32_t wasm_function_table_size_reference() const;
Address global_handle() const;
Address js_to_wasm_address() const;
Address wasm_call_address() const;
void set_wasm_context_reference(
......@@ -519,6 +522,9 @@ class RelocInfo {
void set_wasm_call_address(
Isolate*, Address,
ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
void set_js_to_wasm_address(
Isolate*, Address,
ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
// this relocation applies to;
// can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
......
......@@ -720,6 +720,28 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallWasmFunction: {
// We must not share code targets for calls to builtins for wasm code, as
// they might need to be patched individually.
internal::Assembler::BlockCodeTargetSharingScope scope;
RelocInfo::Mode rmode = RelocInfo::JS_TO_WASM_CALL;
if (info()->IsWasm()) {
scope.Open(tasm());
rmode = RelocInfo::WASM_CALL;
}
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt32());
__ Call(wasm_code, rmode);
} else {
__ Call(i.InputRegister(0));
}
RecordCallPosition(instr);
DCHECK_EQ(LeaveCC, i.OutputSBit());
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject: {
// We must not share code targets for calls to builtins for wasm code, as
......@@ -745,6 +767,29 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
// We must not share code targets for calls to builtins for wasm code, as
// they might need to be patched individually.
internal::Assembler::BlockCodeTargetSharingScope scope;
RelocInfo::Mode rmode = RelocInfo::JS_TO_WASM_CALL;
if (info()->IsWasm()) {
scope.Open(tasm());
rmode = RelocInfo::WASM_CALL;
}
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt32());
__ Jump(wasm_code, rmode);
} else {
__ Jump(i.InputRegister(0));
}
DCHECK_EQ(LeaveCC, i.OutputSBit());
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
__ Jump(i.InputRegister(0));
......
......@@ -715,6 +715,40 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallWasmFunction: {
// We must not share code targets for calls to builtins for wasm code, as
// they might need to be patched individually.
internal::Assembler::BlockCodeTargetSharingScope scope;
if (info()->IsWasm()) scope.Open(tasm());
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt64());
if (info()->IsWasm()) {
__ Call(wasm_code, RelocInfo::WASM_CALL);
} else {
__ Call(wasm_code, RelocInfo::JS_TO_WASM_CALL);
}
} else {
Register target = i.InputRegister(0);
__ Call(target);
}
RecordCallPosition(instr);
// TODO(titzer): this is ugly. JSSP should be a caller-save register
// in this case, but it is not possible to express in the register
// allocator.
CallDescriptor::Flags flags(MiscField::decode(opcode));
if (flags & CallDescriptor::kRestoreJSSP) {
__ Ldr(jssp, MemOperand(csp));
__ Mov(csp, jssp);
}
if (flags & CallDescriptor::kRestoreCSP) {
__ Mov(csp, jssp);
__ AssertCspAligned();
}
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject: {
// We must not share code targets for calls to builtins for wasm code, as
......@@ -739,6 +773,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
// We must not share code targets for calls to builtins for wasm code, as
// they might need to be patched individually.
internal::Assembler::BlockCodeTargetSharingScope scope;
if (info()->IsWasm()) scope.Open(tasm());
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt64());
if (info()->IsWasm()) {
__ Jump(wasm_code, RelocInfo::WASM_CALL);
} else {
__ Jump(wasm_code, RelocInfo::JS_TO_WASM_CALL);
}
} else {
Register target = i.InputRegister(0);
__ Jump(target);
}
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
__ Jump(i.InputRegister(0));
......@@ -2572,7 +2630,8 @@ void CodeGenerator::AssembleConstructFrame() {
__ Claim(shrink_slots);
}
break;
case CallDescriptor::kCallCodeObject: {
case CallDescriptor::kCallCodeObject:
case CallDescriptor::kCallWasmFunction: {
UseScratchRegisterScope temps(tasm());
__ Claim(shrink_slots + 1); // Claim extra slot for frame type marker.
Register scratch = temps.AcquireX();
......
......@@ -960,6 +960,23 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallWasmFunction: {
if (HasImmediateInput(instr, 0)) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt32());
if (info()->IsWasm()) {
__ wasm_call(wasm_code, RelocInfo::WASM_CALL);
} else {
__ call(wasm_code, RelocInfo::JS_TO_WASM_CALL);
}
} else {
Register reg = i.InputRegister(0);
__ call(reg);
}
RecordCallPosition(instr);
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject: {
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
......@@ -978,6 +995,23 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (HasImmediateInput(instr, 0)) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt32());
if (info()->IsWasm()) {
__ jmp(wasm_code, RelocInfo::WASM_CALL);
} else {
__ jmp(wasm_code, RelocInfo::JS_TO_WASM_CALL);
}
} else {
Register reg = i.InputRegister(0);
__ jmp(reg);
}
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!HasImmediateInput(instr, 0));
Register reg = i.InputRegister(0);
......
......@@ -51,6 +51,8 @@ enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny };
V(ArchRestoreCallerRegisters) \
V(ArchCallCFunction) \
V(ArchPrepareTailCall) \
V(ArchCallWasmFunction) \
V(ArchTailCallWasm) \
V(ArchJmp) \
V(ArchLookupSwitch) \
V(ArchTableSwitch) \
......
......@@ -296,11 +296,13 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
case kArchCallCFunction:
case kArchCallCodeObject:
case kArchCallJSFunction:
case kArchCallWasmFunction:
return kHasSideEffect;
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject:
case kArchTailCallAddress:
case kArchTailCallWasm:
return kHasSideEffect | kIsBlockTerminator;
case kArchDeoptimize:
......
......@@ -759,6 +759,14 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
? g.UseImmediate(callee)
: g.UseRegister(callee));
break;
case CallDescriptor::kCallWasmFunction:
buffer->instruction_args.push_back(
(call_address_immediate &&
(callee->opcode() == IrOpcode::kRelocatableInt64Constant ||
callee->opcode() == IrOpcode::kRelocatableInt32Constant))
? g.UseImmediate(callee)
: g.UseRegister(callee));
break;
case CallDescriptor::kCallJSFunction:
buffer->instruction_args.push_back(
g.UseLocation(callee, buffer->descriptor->GetInputLocation(0)));
......@@ -2589,6 +2597,9 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
case CallDescriptor::kCallJSFunction:
opcode = kArchCallJSFunction | MiscField::encode(flags);
break;
case CallDescriptor::kCallWasmFunction:
opcode = kArchCallWasmFunction | MiscField::encode(flags);
break;
}
// Emit the call instruction.
......@@ -2655,6 +2666,9 @@ void InstructionSelector::VisitTailCall(Node* node) {
case CallDescriptor::kCallAddress:
opcode = kArchTailCallAddress;
break;
case CallDescriptor::kCallWasmFunction:
opcode = kArchTailCallWasm;
break;
default:
UNREACHABLE();
return;
......
......@@ -901,7 +901,8 @@ class V8_EXPORT_PRIVATE Instruction final {
bool IsTailCall() const {
return arch_opcode() == ArchOpcode::kArchTailCallCodeObject ||
arch_opcode() == ArchOpcode::kArchTailCallCodeObjectFromJSFunction ||
arch_opcode() == ArchOpcode::kArchTailCallAddress;
arch_opcode() == ArchOpcode::kArchTailCallAddress ||
arch_opcode() == ArchOpcode::kArchTailCallWasm;
}
bool IsThrow() const {
return arch_opcode() == ArchOpcode::kArchThrowTerminator;
......
......@@ -37,6 +37,9 @@ std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
case CallDescriptor::kCallAddress:
os << "Addr";
break;
case CallDescriptor::kCallWasmFunction:
os << "Wasm";
break;
}
return os;
}
......@@ -117,6 +120,7 @@ int CallDescriptor::CalculateFixedFrameSize() const {
CommonFrameConstants::kCPSlotCount;
break;
case kCallCodeObject:
case kCallWasmFunction:
return TypedFrameConstants::kFixedSlotCount;
}
UNREACHABLE();
......
......@@ -166,9 +166,10 @@ class V8_EXPORT_PRIVATE CallDescriptor final
public:
// Describes the kind of this call, which determines the target.
enum Kind {
kCallCodeObject, // target is a Code object
kCallJSFunction, // target is a JSFunction object
kCallAddress // target is a machine pointer
kCallCodeObject, // target is a Code object
kCallJSFunction, // target is a JSFunction object
kCallAddress, // target is a machine pointer
kCallWasmFunction // target is a wasm function
};
enum Flag {
......
......@@ -780,6 +780,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallWasmFunction: {
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt32());
__ Call(wasm_code, info()->IsWasm() ? RelocInfo::WASM_CALL
: RelocInfo::JS_TO_WASM_CALL);
} else {
__ Call(at, i.InputRegister(0), 0);
}
RecordCallPosition(instr);
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject: {
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
......@@ -796,6 +809,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt32());
__ Jump(wasm_code, info()->IsWasm() ? RelocInfo::WASM_CALL
: RelocInfo::JS_TO_WASM_CALL);
} else {
__ Jump(at, i.InputRegister(0), 0);
}
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
__ Jump(i.InputRegister(0));
......
......@@ -824,6 +824,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallWasmFunction: {
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
i.TempRegister(0), i.TempRegister(1),
i.TempRegister(2));
}
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt64());
__ Jump(wasm_code, info()->IsWasm() ? RelocInfo::WASM_CALL
: RelocInfo::JS_TO_WASM_CALL);
} else {
__ daddiu(at, i.InputRegister(0), 0);
__ Jump(at);
}
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject: {
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
......@@ -841,6 +860,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (instr->InputAt(0)->IsImmediate()) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt64());
__ Jump(wasm_code, info()->IsWasm() ? RelocInfo::WASM_CALL
: RelocInfo::JS_TO_WASM_CALL);
} else {
__ daddiu(at, i.InputRegister(0), 0);
__ Jump(at);
}
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
__ Jump(i.InputRegister(0));
......
......@@ -860,6 +860,23 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallWasmFunction: {
if (HasImmediateInput(instr, 0)) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt64());
if (info()->IsWasm()) {
__ near_call(wasm_code, RelocInfo::WASM_CALL);
} else {
__ Call(wasm_code, RelocInfo::JS_TO_WASM_CALL);
}
} else {
Register reg = i.InputRegister(0);
__ call(reg);
}
RecordCallPosition(instr);
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObjectFromJSFunction:
case kArchTailCallCodeObject: {
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
......@@ -880,6 +897,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (HasImmediateInput(instr, 0)) {
Address wasm_code = reinterpret_cast<Address>(
i.ToConstant(instr->InputAt(0)).ToInt64());
if (info()->IsWasm()) {
__ near_jmp(wasm_code, RelocInfo::WASM_CALL);
} else {
__ Move(kScratchRegister, wasm_code, RelocInfo::JS_TO_WASM_CALL);
__ jmp(kScratchRegister);
}
} else {
Register reg = i.InputRegister(0);
__ jmp(reg);
}
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!HasImmediateInput(instr, 0));
Register reg = i.InputRegister(0);
......
......@@ -56,7 +56,8 @@ static const int kNoCodeAgeSequenceLength = 5;
// The modes possibly affected by apply must be in kApplyMask.
void RelocInfo::apply(intptr_t delta) {
if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) {
if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_) ||
rmode_ == RelocInfo::JS_TO_WASM_CALL) {
int32_t* p = reinterpret_cast<int32_t*>(pc_);
*p -= delta; // Relocate entry.
} else if (IsInternalReference(rmode_)) {
......@@ -68,14 +69,13 @@ void RelocInfo::apply(intptr_t delta) {
Address RelocInfo::target_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE);
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
return reinterpret_cast<Address>(pc_);
}
......@@ -270,7 +270,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc, Code* code,
Address target,
ICacheFlushMode icache_flush_mode) {
Address constant_pool = code ? code->constant_pool() : nullptr;
set_target_address_at(isolate, pc, constant_pool, target);
set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode);
}
Address Assembler::target_address_from_return_address(Address pc) {
......
......@@ -186,9 +186,9 @@ void Displacement::init(Label* L, Type type) {
// -----------------------------------------------------------------------------
// Implementation of RelocInfo
const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
1 << RelocInfo::RUNTIME_ENTRY |
1 << RelocInfo::INTERNAL_REFERENCE;
const int RelocInfo::kApplyMask =
RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::JS_TO_WASM_CALL;
bool RelocInfo::IsCodedSpecially() {
// The deserializer needs to know whether a pointer is specially coded. Being
......@@ -223,6 +223,18 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
}
}
void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
Assembler::set_target_address_at(isolate, pc_, constant_pool_, address,
icache_flush_mode);
}
Address RelocInfo::js_to_wasm_address() const {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
return Assembler::target_address_at(pc_, constant_pool_);
}
// -----------------------------------------------------------------------------
// Implementation of Operand
......@@ -1631,6 +1643,11 @@ void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
}
}
void Assembler::wasm_call(Address entry, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
EMIT(0xE8);
emit(reinterpret_cast<intptr_t>(entry), rmode);
}
int Assembler::CallSize(const Operand& adr) {
// Call size is 1 (opcode) + adr.len_ (operand).
......@@ -1700,7 +1717,6 @@ void Assembler::jmp(Label* L, Label::Distance distance) {
}
}
void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
DCHECK(!RelocInfo::IsCodeTarget(rmode));
......
......@@ -857,6 +857,7 @@ class Assembler : public AssemblerBase {
int CallSize(Handle<Code> code, RelocInfo::Mode mode);
void call(Handle<Code> code, RelocInfo::Mode rmode);
void call(CodeStub* stub);
void wasm_call(Address address, RelocInfo::Mode rmode);
// Jumps
// unconditional jump to L
......
......@@ -210,6 +210,17 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
reinterpret_cast<Address>(size), flush_mode);
}
void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
set_embedded_address(isolate, address, icache_flush_mode);
}
Address RelocInfo::js_to_wasm_address() const {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
return embedded_address();
}
// -----------------------------------------------------------------------------
// Implementation of Operand and MemOperand.
// See assembler-mips-inl.h for inlined constructors.
......
......@@ -189,6 +189,17 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
reinterpret_cast<Address>(size), flush_mode);
}
void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
set_embedded_address(isolate, address, icache_flush_mode);
}
Address RelocInfo::js_to_wasm_address() const {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
return embedded_address();
}
// -----------------------------------------------------------------------------
// Implementation of Operand and MemOperand.
// See assembler-mips-inl.h for inlined constructors.
......
......@@ -329,14 +329,13 @@ void RelocInfo::apply(intptr_t delta) {
Address RelocInfo::target_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
return Assembler::target_address_at(pc_, host_);
}
Address RelocInfo::target_address_address() {
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE);
DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_) ||
rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
return reinterpret_cast<Address>(pc_);
}
......
......@@ -143,6 +143,17 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
}
}
void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
set_embedded_address(isolate, address, icache_flush_mode);
}
Address RelocInfo::js_to_wasm_address() const {
DCHECK_EQ(rmode_, JS_TO_WASM_CALL);
return embedded_address();
}
// -----------------------------------------------------------------------------
// Implementation of Operand
......@@ -953,6 +964,23 @@ void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
emit_code_target(target, rmode);
}
void Assembler::near_call(Address addr, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
emit(0xE8);
intptr_t value = reinterpret_cast<intptr_t>(addr);
DCHECK(is_int32(value));
RecordRelocInfo(rmode);
emitl(static_cast<int32_t>(value));
}
void Assembler::near_jmp(Address addr, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
emit(0xE9);
intptr_t value = reinterpret_cast<intptr_t>(addr);
DCHECK(is_int32(value));
RecordRelocInfo(rmode);
emitl(static_cast<int32_t>(value));
}
void Assembler::call(Register adr) {
EnsureSpace ensure_space(this);
......@@ -4856,9 +4884,9 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
reloc_info_writer.Write(&rinfo);
}
const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
1 << RelocInfo::RUNTIME_ENTRY |
1 << RelocInfo::INTERNAL_REFERENCE;
const int RelocInfo::kApplyMask =
RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::WASM_CALL;
bool RelocInfo::IsCodedSpecially() {
// The deserializer needs to know whether a pointer is specially coded. Being
......
......@@ -885,6 +885,8 @@ class Assembler : public AssemblerBase {
// Call near relative 32-bit displacement, relative to next instruction.
void call(Label* L);
void call(Address entry, RelocInfo::Mode rmode);
void near_call(Address entry, RelocInfo::Mode rmode);
void near_jmp(Address entry, RelocInfo::Mode rmode);
void call(CodeStub* stub);
void call(Handle<Code> target,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);
......
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