Commit b1cd08da authored by Jaideep Bajwa's avatar Jaideep Bajwa Committed by Commit Bot

PPC/s390: [iwyu] Remove illegal inline include from "macro-assembler.h"

Port bc69f345

R=mstarzinger@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: I88f0167a43fb7eb7967169a84466de3aedf00125
Reviewed-on: https://chromium-review.googlesource.com/666299
Commit-Queue: Jaideep Bajwa <bjaideep@ca.ibm.com>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48014}
parent b0693158
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#if V8_TARGET_ARCH_PPC #if V8_TARGET_ARCH_PPC
#include "src/assembler-inl.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/deoptimizer.h" #include "src/deoptimizer.h"
...@@ -1405,7 +1406,7 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) { ...@@ -1405,7 +1406,7 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
__ mov(scratch0, __ mov(scratch0,
Operand(ExternalReference::builtins_address(masm->isolate()))); Operand(ExternalReference::builtins_address(masm->isolate())));
__ ShiftLeftImm(scratch1, scratch1, Operand(kPointerSizeLog2)); __ ShiftLeftImm(scratch1, scratch1, Operand(kPointerSizeLog2));
__ LoadP(scratch1, MemOperand(scratch0, scratch1)); __ LoadPX(scratch1, MemOperand(scratch0, scratch1));
// Check if the loaded code object has already been deserialized. This is // Check if the loaded code object has already been deserialized. This is
// the case iff it does not equal DeserializeLazy. // the case iff it does not equal DeserializeLazy.
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#if V8_TARGET_ARCH_S390 #if V8_TARGET_ARCH_S390
#include "src/assembler-inl.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/deoptimizer.h" #include "src/deoptimizer.h"
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "src/compiler/code-generator.h" #include "src/compiler/code-generator.h"
#include "src/assembler-inl.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "src/compiler/code-generator.h" #include "src/compiler/code-generator.h"
#include "src/assembler-inl.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
......
...@@ -254,40 +254,8 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { ...@@ -254,40 +254,8 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
} }
} }
Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) : rmode_(rmode) {
value_.immediate = immediate;
}
Operand::Operand(const ExternalReference& f)
: rmode_(RelocInfo::EXTERNAL_REFERENCE) {
value_.immediate = reinterpret_cast<intptr_t>(f.address());
}
Operand::Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR) {
value_.immediate = reinterpret_cast<intptr_t>(value);
}
Operand::Operand(Register rm) : rm_(rm), rmode_(kRelocInfo_NONEPTR) {} Operand::Operand(Register rm) : rm_(rm), rmode_(kRelocInfo_NONEPTR) {}
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
void Assembler::TrackBranch() {
DCHECK(!trampoline_emitted_);
int count = tracked_branch_count_++;
if (count == 0) {
// We leave space (kMaxBlockTrampolineSectionSize)
// for BlockTrampolinePoolScope buffer.
next_trampoline_check_ =
pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
} else {
next_trampoline_check_ -= kTrampolineSlotsSize;
}
}
void Assembler::UntrackBranch() { void Assembler::UntrackBranch() {
DCHECK(!trampoline_emitted_); DCHECK(!trampoline_emitted_);
DCHECK(tracked_branch_count_ > 0); DCHECK(tracked_branch_count_ > 0);
...@@ -300,22 +268,6 @@ void Assembler::UntrackBranch() { ...@@ -300,22 +268,6 @@ void Assembler::UntrackBranch() {
} }
} }
void Assembler::CheckTrampolinePoolQuick() {
if (pc_offset() >= next_trampoline_check_) {
CheckTrampolinePool();
}
}
void Assembler::emit(Instr x) {
CheckBuffer();
*reinterpret_cast<Instr*>(pc_) = x;
pc_ += kInstrSize;
CheckTrampolinePoolQuick();
}
bool Operand::is_reg() const { return rm_.is_valid(); }
// Fetch the 32bit value from the FIXED_SEQUENCE lis/ori // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori
Address Assembler::target_address_at(Address pc, Address constant_pool) { Address Assembler::target_address_at(Address pc, Address constant_pool) {
if (FLAG_enable_embedded_constant_pool && constant_pool) { if (FLAG_enable_embedded_constant_pool && constant_pool) {
......
...@@ -383,12 +383,19 @@ class Operand BASE_EMBEDDED { ...@@ -383,12 +383,19 @@ class Operand BASE_EMBEDDED {
public: public:
// immediate // immediate
INLINE(explicit Operand(intptr_t immediate, INLINE(explicit Operand(intptr_t immediate,
RelocInfo::Mode rmode = kRelocInfo_NONEPTR)); RelocInfo::Mode rmode = kRelocInfo_NONEPTR)
: rmode_(rmode)) {
value_.immediate = immediate;
}
INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); } INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); }
INLINE(explicit Operand(const ExternalReference& f)); INLINE(explicit Operand(const ExternalReference& f)
: rmode_(RelocInfo::EXTERNAL_REFERENCE)) {
value_.immediate = reinterpret_cast<intptr_t>(f.address());
}
explicit Operand(Handle<HeapObject> handle); explicit Operand(Handle<HeapObject> handle);
INLINE(explicit Operand(Smi* value)); INLINE(explicit Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR)) {
value_.immediate = reinterpret_cast<intptr_t>(value);
}
// rm // rm
INLINE(explicit Operand(Register rm)); INLINE(explicit Operand(Register rm));
...@@ -396,7 +403,7 @@ class Operand BASE_EMBEDDED { ...@@ -396,7 +403,7 @@ class Operand BASE_EMBEDDED {
static Operand EmbeddedCode(CodeStub* stub); static Operand EmbeddedCode(CodeStub* stub);
// Return true if this is a register operand. // Return true if this is a register operand.
INLINE(bool is_reg() const); INLINE(bool is_reg() const) { return rm_.is_valid(); }
bool must_output_reloc_info(const Assembler* assembler) const; bool must_output_reloc_info(const Assembler* assembler) const;
...@@ -1533,13 +1540,39 @@ class Assembler : public AssemblerBase { ...@@ -1533,13 +1540,39 @@ class Assembler : public AssemblerBase {
ConstantPoolBuilder constant_pool_builder_; ConstantPoolBuilder constant_pool_builder_;
// Code emission void CheckBuffer() {
inline void CheckBuffer(); if (buffer_space() <= kGap) {
GrowBuffer();
}
}
void GrowBuffer(int needed = 0); void GrowBuffer(int needed = 0);
inline void emit(Instr x); // Code emission
inline void TrackBranch(); void emit(Instr x) {
CheckBuffer();
*reinterpret_cast<Instr*>(pc_) = x;
pc_ += kInstrSize;
CheckTrampolinePoolQuick();
}
void TrackBranch() {
DCHECK(!trampoline_emitted_);
int count = tracked_branch_count_++;
if (count == 0) {
// We leave space (kMaxBlockTrampolineSectionSize)
// for BlockTrampolinePoolScope buffer.
next_trampoline_check_ =
pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
} else {
next_trampoline_check_ -= kTrampolineSlotsSize;
}
}
inline void UntrackBranch(); inline void UntrackBranch();
inline void CheckTrampolinePoolQuick(); void CheckTrampolinePoolQuick() {
if (pc_offset() >= next_trampoline_check_) {
CheckTrampolinePool();
}
}
// Instruction generation // Instruction generation
void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#if V8_TARGET_ARCH_PPC #if V8_TARGET_ARCH_PPC
#include "src/api-arguments.h" #include "src/api-arguments.h"
#include "src/assembler-inl.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
...@@ -1007,6 +1008,49 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( ...@@ -1007,6 +1008,49 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
stub2.GetCode(); stub2.GetCode();
} }
RecordWriteStub::Mode RecordWriteStub::GetMode(Code* stub) {
Instr first_instruction =
Assembler::instr_at(stub->instruction_start() + Assembler::kInstrSize);
Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
(Assembler::kInstrSize * 2));
// Consider adding DCHECK here to catch unexpected instruction sequence
if (BF == (first_instruction & kBOfieldMask)) {
return INCREMENTAL;
}
if (BF == (second_instruction & kBOfieldMask)) {
return INCREMENTAL_COMPACTION;
}
return STORE_BUFFER_ONLY;
}
void RecordWriteStub::Patch(Code* stub, Mode mode) {
MacroAssembler masm(stub->GetIsolate(), stub->instruction_start(),
stub->instruction_size(), CodeObjectRequired::kNo);
switch (mode) {
case STORE_BUFFER_ONLY:
DCHECK(GetMode(stub) == INCREMENTAL ||
GetMode(stub) == INCREMENTAL_COMPACTION);
PatchBranchIntoNop(&masm, Assembler::kInstrSize);
PatchBranchIntoNop(&masm, Assembler::kInstrSize * 2);
break;
case INCREMENTAL:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchNopIntoBranch(&masm, Assembler::kInstrSize);
break;
case INCREMENTAL_COMPACTION:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchNopIntoBranch(&masm, Assembler::kInstrSize * 2);
break;
}
DCHECK(GetMode(stub) == mode);
Assembler::FlushICache(stub->GetIsolate(),
stub->instruction_start() + Assembler::kInstrSize,
2 * Assembler::kInstrSize);
}
// Takes the input in 3 registers: address_ value_ and object_. A pointer to // Takes the input in 3 registers: address_ value_ and object_. A pointer to
// the value has just been written into the object, now this stub makes sure // the value has just been written into the object, now this stub makes sure
...@@ -1097,6 +1141,9 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { ...@@ -1097,6 +1141,9 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode()); regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode());
} }
void RecordWriteStub::Activate(Code* code) {
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
void RecordWriteStub::CheckNeedsToInformIncrementalMarker( void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need, MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
......
...@@ -94,49 +94,9 @@ class RecordWriteStub : public PlatformCodeStub { ...@@ -94,49 +94,9 @@ class RecordWriteStub : public PlatformCodeStub {
masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BF); masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BF);
} }
static Mode GetMode(Code* stub) { static Mode GetMode(Code* stub);
Instr first_instruction =
Assembler::instr_at(stub->instruction_start() + Assembler::kInstrSize);
Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
(Assembler::kInstrSize * 2));
// Consider adding DCHECK here to catch unexpected instruction sequence
if (BF == (first_instruction & kBOfieldMask)) {
return INCREMENTAL;
}
if (BF == (second_instruction & kBOfieldMask)) {
return INCREMENTAL_COMPACTION;
}
return STORE_BUFFER_ONLY;
}
static void Patch(Code* stub, Mode mode) { static void Patch(Code* stub, Mode mode);
MacroAssembler masm(stub->GetIsolate(), stub->instruction_start(),
stub->instruction_size(), CodeObjectRequired::kNo);
switch (mode) {
case STORE_BUFFER_ONLY:
DCHECK(GetMode(stub) == INCREMENTAL ||
GetMode(stub) == INCREMENTAL_COMPACTION);
PatchBranchIntoNop(&masm, Assembler::kInstrSize);
PatchBranchIntoNop(&masm, Assembler::kInstrSize * 2);
break;
case INCREMENTAL:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchNopIntoBranch(&masm, Assembler::kInstrSize);
break;
case INCREMENTAL_COMPACTION:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchNopIntoBranch(&masm, Assembler::kInstrSize * 2);
break;
}
DCHECK(GetMode(stub) == mode);
Assembler::FlushICache(stub->GetIsolate(),
stub->instruction_start() + Assembler::kInstrSize,
2 * Assembler::kInstrSize);
}
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
...@@ -216,9 +176,7 @@ class RecordWriteStub : public PlatformCodeStub { ...@@ -216,9 +176,7 @@ class RecordWriteStub : public PlatformCodeStub {
Mode mode); Mode mode);
void InformIncrementalMarker(MacroAssembler* masm); void InformIncrementalMarker(MacroAssembler* masm);
void Activate(Code* code) override { void Activate(Code* code) override;
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
Register object() const { Register object() const {
return Register::from_code(ObjectBits::decode(minor_key_)); return Register::from_code(ObjectBits::decode(minor_key_));
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/assembler-inl.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/deoptimizer.h" #include "src/deoptimizer.h"
#include "src/register-configuration.h" #include "src/register-configuration.h"
......
...@@ -27,6 +27,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size, ...@@ -27,6 +27,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size,
CodeObjectRequired create_code_object) CodeObjectRequired create_code_object)
: TurboAssembler(isolate, buffer, size, create_code_object) {} : TurboAssembler(isolate, buffer, size, create_code_object) {}
TurboAssembler::TurboAssembler(Isolate* isolate, void* buffer, int buffer_size,
CodeObjectRequired create_code_object)
: Assembler(isolate, buffer, buffer_size), isolate_(isolate) {
if (create_code_object == CodeObjectRequired::kYes) {
code_object_ =
Handle<HeapObject>::New(isolate->heap()->undefined_value(), isolate);
}
}
int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode, int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion1, Register exclusion1,
Register exclusion2, Register exclusion2,
......
...@@ -108,13 +108,8 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg, ...@@ -108,13 +108,8 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
class TurboAssembler : public Assembler { class TurboAssembler : public Assembler {
public: public:
TurboAssembler(Isolate* isolate, void* buffer, int buffer_size, TurboAssembler(Isolate* isolate, void* buffer, int buffer_size,
CodeObjectRequired create_code_object) CodeObjectRequired create_code_object);
: Assembler(isolate, buffer, buffer_size), isolate_(isolate) {
if (create_code_object == CodeObjectRequired::kYes) {
code_object_ =
Handle<HeapObject>::New(isolate->heap()->undefined_value(), isolate);
}
}
void set_has_frame(bool value) { has_frame_ = value; } void set_has_frame(bool value) { has_frame_ = value; }
bool has_frame() { return has_frame_; } bool has_frame() { return has_frame_; }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/regexp/ppc/regexp-macro-assembler-ppc.h" #include "src/regexp/ppc/regexp-macro-assembler-ppc.h"
#include "src/assembler-inl.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/log.h" #include "src/log.h"
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#if V8_TARGET_ARCH_S390 #if V8_TARGET_ARCH_S390
#include "src/assembler-inl.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/log.h" #include "src/log.h"
......
...@@ -233,27 +233,8 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { ...@@ -233,27 +233,8 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
} }
// Operand constructors // Operand constructors
Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) : rmode_(rmode) {
value_.immediate = immediate;
}
Operand::Operand(const ExternalReference& f)
: rmode_(RelocInfo::EXTERNAL_REFERENCE) {
value_.immediate = reinterpret_cast<intptr_t>(f.address());
}
Operand::Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR) {
value_.immediate = reinterpret_cast<intptr_t>(value);
}
Operand::Operand(Register rm) : rm_(rm), rmode_(kRelocInfo_NONEPTR) {} Operand::Operand(Register rm) : rm_(rm), rmode_(kRelocInfo_NONEPTR) {}
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
int32_t Assembler::emit_code_target(Handle<Code> target, int32_t Assembler::emit_code_target(Handle<Code> target,
RelocInfo::Mode rmode) { RelocInfo::Mode rmode) {
DCHECK(RelocInfo::IsCodeTarget(rmode)); DCHECK(RelocInfo::IsCodeTarget(rmode));
...@@ -270,60 +251,6 @@ int32_t Assembler::emit_code_target(Handle<Code> target, ...@@ -270,60 +251,6 @@ int32_t Assembler::emit_code_target(Handle<Code> target,
return current; return current;
} }
// Helper to emit the binary encoding of a 2 byte instruction
void Assembler::emit2bytes(uint16_t x) {
CheckBuffer();
#if V8_TARGET_LITTLE_ENDIAN
// We need to emit instructions in big endian format as disassembler /
// simulator require the first byte of the instruction in order to decode
// the instruction length. Swap the bytes.
x = ((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8);
#endif
*reinterpret_cast<uint16_t*>(pc_) = x;
pc_ += 2;
}
// Helper to emit the binary encoding of a 4 byte instruction
void Assembler::emit4bytes(uint32_t x) {
CheckBuffer();
#if V8_TARGET_LITTLE_ENDIAN
// We need to emit instructions in big endian format as disassembler /
// simulator require the first byte of the instruction in order to decode
// the instruction length. Swap the bytes.
x = ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) |
((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24);
#endif
*reinterpret_cast<uint32_t*>(pc_) = x;
pc_ += 4;
}
// Helper to emit the binary encoding of a 6 byte instruction
void Assembler::emit6bytes(uint64_t x) {
CheckBuffer();
#if V8_TARGET_LITTLE_ENDIAN
// We need to emit instructions in big endian format as disassembler /
// simulator require the first byte of the instruction in order to decode
// the instruction length. Swap the bytes.
x = (static_cast<uint64_t>(x & 0xFF) << 40) |
(static_cast<uint64_t>((x >> 8) & 0xFF) << 32) |
(static_cast<uint64_t>((x >> 16) & 0xFF) << 24) |
(static_cast<uint64_t>((x >> 24) & 0xFF) << 16) |
(static_cast<uint64_t>((x >> 32) & 0xFF) << 8) |
(static_cast<uint64_t>((x >> 40) & 0xFF));
x |= (*reinterpret_cast<uint64_t*>(pc_) >> 48) << 48;
#else
// We need to pad two bytes of zeros in order to get the 6-bytes
// stored from low address.
x = x << 16;
x |= *reinterpret_cast<uint64_t*>(pc_) & 0xFFFF;
#endif
// It is safe to store 8-bytes, as CheckBuffer() guarantees we have kGap
// space left over.
*reinterpret_cast<uint64_t*>(pc_) = x;
pc_ += 6;
}
bool Operand::is_reg() const { return rm_.is_valid(); }
// Fetch the 32bit value from the FIXED_SEQUENCE IIHF / IILF // Fetch the 32bit value from the FIXED_SEQUENCE IIHF / IILF
Address Assembler::target_address_at(Address pc, Address constant_pool) { Address Assembler::target_address_at(Address pc, Address constant_pool) {
......
...@@ -368,11 +368,19 @@ class Operand BASE_EMBEDDED { ...@@ -368,11 +368,19 @@ class Operand BASE_EMBEDDED {
public: public:
// immediate // immediate
INLINE(explicit Operand(intptr_t immediate, INLINE(explicit Operand(intptr_t immediate,
RelocInfo::Mode rmode = kRelocInfo_NONEPTR)); RelocInfo::Mode rmode = kRelocInfo_NONEPTR)
: rmode_(rmode)) {
value_.immediate = immediate;
}
INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); } INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); }
INLINE(explicit Operand(const ExternalReference& f)); INLINE(explicit Operand(const ExternalReference& f)
: rmode_(RelocInfo::EXTERNAL_REFERENCE)) {
value_.immediate = reinterpret_cast<intptr_t>(f.address());
}
explicit Operand(Handle<HeapObject> handle); explicit Operand(Handle<HeapObject> handle);
INLINE(explicit Operand(Smi* value)); INLINE(explicit Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR)) {
value_.immediate = reinterpret_cast<intptr_t>(value);
}
// rm // rm
INLINE(explicit Operand(Register rm)); INLINE(explicit Operand(Register rm));
...@@ -380,7 +388,7 @@ class Operand BASE_EMBEDDED { ...@@ -380,7 +388,7 @@ class Operand BASE_EMBEDDED {
static Operand EmbeddedNumber(double value); // Smi or HeapNumber static Operand EmbeddedNumber(double value); // Smi or HeapNumber
// Return true if this is a register operand. // Return true if this is a register operand.
INLINE(bool is_reg() const); INLINE(bool is_reg() const) { return rm_.is_valid(); }
bool must_output_reloc_info(const Assembler* assembler) const; bool must_output_reloc_info(const Assembler* assembler) const;
...@@ -1438,7 +1446,11 @@ class Assembler : public AssemblerBase { ...@@ -1438,7 +1446,11 @@ class Assembler : public AssemblerBase {
int last_bound_pos_; int last_bound_pos_;
// Code emission // Code emission
inline void CheckBuffer(); void CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
void GrowBuffer(int needed = 0); void GrowBuffer(int needed = 0);
inline void TrackBranch(); inline void TrackBranch();
inline void UntrackBranch(); inline void UntrackBranch();
...@@ -1446,10 +1458,58 @@ class Assembler : public AssemblerBase { ...@@ -1446,10 +1458,58 @@ class Assembler : public AssemblerBase {
inline int32_t emit_code_target( inline int32_t emit_code_target(
Handle<Code> target, RelocInfo::Mode rmode); Handle<Code> target, RelocInfo::Mode rmode);
// Helpers to emit binary encoding of 2/4/6 byte instructions. // Helper to emit the binary encoding of a 2 byte instruction
inline void emit2bytes(uint16_t x); void emit2bytes(uint16_t x) {
inline void emit4bytes(uint32_t x); CheckBuffer();
inline void emit6bytes(uint64_t x); #if V8_TARGET_LITTLE_ENDIAN
// We need to emit instructions in big endian format as disassembler /
// simulator require the first byte of the instruction in order to decode
// the instruction length. Swap the bytes.
x = ((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8);
#endif
*reinterpret_cast<uint16_t*>(pc_) = x;
pc_ += 2;
}
// Helper to emit the binary encoding of a 4 byte instruction
void emit4bytes(uint32_t x) {
CheckBuffer();
#if V8_TARGET_LITTLE_ENDIAN
// We need to emit instructions in big endian format as disassembler /
// simulator require the first byte of the instruction in order to decode
// the instruction length. Swap the bytes.
x = ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) |
((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24);
#endif
*reinterpret_cast<uint32_t*>(pc_) = x;
pc_ += 4;
}
// Helper to emit the binary encoding of a 6 byte instruction
void emit6bytes(uint64_t x) {
CheckBuffer();
#if V8_TARGET_LITTLE_ENDIAN
// We need to emit instructions in big endian format as disassembler /
// simulator require the first byte of the instruction in order to decode
// the instruction length. Swap the bytes.
x = (static_cast<uint64_t>(x & 0xFF) << 40) |
(static_cast<uint64_t>((x >> 8) & 0xFF) << 32) |
(static_cast<uint64_t>((x >> 16) & 0xFF) << 24) |
(static_cast<uint64_t>((x >> 24) & 0xFF) << 16) |
(static_cast<uint64_t>((x >> 32) & 0xFF) << 8) |
(static_cast<uint64_t>((x >> 40) & 0xFF));
x |= (*reinterpret_cast<uint64_t*>(pc_) >> 48) << 48;
#else
// We need to pad two bytes of zeros in order to get the 6-bytes
// stored from low address.
x = x << 16;
x |= *reinterpret_cast<uint64_t*>(pc_) & 0xFFFF;
#endif
// It is safe to store 8-bytes, as CheckBuffer() guarantees we have kGap
// space left over.
*reinterpret_cast<uint64_t*>(pc_) = x;
pc_ += 6;
}
// Helpers to emit binary encoding for various instruction formats. // Helpers to emit binary encoding for various instruction formats.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#if V8_TARGET_ARCH_S390 #if V8_TARGET_ARCH_S390
#include "src/api-arguments.h" #include "src/api-arguments.h"
#include "src/assembler-inl.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
...@@ -986,6 +987,64 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( ...@@ -986,6 +987,64 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
StoreBufferOverflowStub stub2(isolate, kSaveFPRegs); StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
stub2.GetCode(); stub2.GetCode();
} }
RecordWriteStub::Mode RecordWriteStub::GetMode(Code* stub) {
int32_t first_instr_length =
Instruction::InstructionLength(stub->instruction_start());
int32_t second_instr_length = Instruction::InstructionLength(
stub->instruction_start() + first_instr_length);
uint64_t first_instr = Assembler::instr_at(stub->instruction_start());
uint64_t second_instr =
Assembler::instr_at(stub->instruction_start() + first_instr_length);
DCHECK(first_instr_length == 4 || first_instr_length == 6);
DCHECK(second_instr_length == 4 || second_instr_length == 6);
bool isFirstInstrNOP = isBranchNop(first_instr, first_instr_length);
bool isSecondInstrNOP = isBranchNop(second_instr, second_instr_length);
// STORE_BUFFER_ONLY has NOP on both branches
if (isSecondInstrNOP && isFirstInstrNOP) return STORE_BUFFER_ONLY;
// INCREMENTAL_COMPACTION has NOP on second branch.
else if (isFirstInstrNOP && !isSecondInstrNOP)
return INCREMENTAL_COMPACTION;
// INCREMENTAL has NOP on first branch.
else if (!isFirstInstrNOP && isSecondInstrNOP)
return INCREMENTAL;
DCHECK(false);
return STORE_BUFFER_ONLY;
}
void RecordWriteStub::Patch(Code* stub, Mode mode) {
MacroAssembler masm(stub->GetIsolate(), stub->instruction_start(),
stub->instruction_size(), CodeObjectRequired::kNo);
// Get instruction lengths of two branches
int32_t first_instr_length = masm.instr_length_at(0);
int32_t second_instr_length = masm.instr_length_at(first_instr_length);
switch (mode) {
case STORE_BUFFER_ONLY:
DCHECK(GetMode(stub) == INCREMENTAL ||
GetMode(stub) == INCREMENTAL_COMPACTION);
PatchBranchCondMask(&masm, 0, CC_NOP);
PatchBranchCondMask(&masm, first_instr_length, CC_NOP);
break;
case INCREMENTAL:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchBranchCondMask(&masm, 0, CC_ALWAYS);
break;
case INCREMENTAL_COMPACTION:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchBranchCondMask(&masm, first_instr_length, CC_ALWAYS);
break;
}
DCHECK(GetMode(stub) == mode);
Assembler::FlushICache(stub->GetIsolate(), stub->instruction_start(),
first_instr_length + second_instr_length);
}
// Takes the input in 3 registers: address_ value_ and object_. A pointer to // Takes the input in 3 registers: address_ value_ and object_. A pointer to
// the value has just been written into the object, now this stub makes sure // the value has just been written into the object, now this stub makes sure
...@@ -1073,6 +1132,10 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { ...@@ -1073,6 +1132,10 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode()); regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode());
} }
void RecordWriteStub::Activate(Code* code) {
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
void RecordWriteStub::CheckNeedsToInformIncrementalMarker( void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need, MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
Mode mode) { Mode mode) {
......
...@@ -108,64 +108,9 @@ class RecordWriteStub : public PlatformCodeStub { ...@@ -108,64 +108,9 @@ class RecordWriteStub : public PlatformCodeStub {
return false; return false;
} }
static Mode GetMode(Code* stub) { static Mode GetMode(Code* stub);
int32_t first_instr_length =
Instruction::InstructionLength(stub->instruction_start());
int32_t second_instr_length = Instruction::InstructionLength(
stub->instruction_start() + first_instr_length);
uint64_t first_instr = Assembler::instr_at(stub->instruction_start());
uint64_t second_instr =
Assembler::instr_at(stub->instruction_start() + first_instr_length);
DCHECK(first_instr_length == 4 || first_instr_length == 6);
DCHECK(second_instr_length == 4 || second_instr_length == 6);
bool isFirstInstrNOP = isBranchNop(first_instr, first_instr_length);
bool isSecondInstrNOP = isBranchNop(second_instr, second_instr_length);
// STORE_BUFFER_ONLY has NOP on both branches
if (isSecondInstrNOP && isFirstInstrNOP) return STORE_BUFFER_ONLY;
// INCREMENTAL_COMPACTION has NOP on second branch.
else if (isFirstInstrNOP && !isSecondInstrNOP)
return INCREMENTAL_COMPACTION;
// INCREMENTAL has NOP on first branch.
else if (!isFirstInstrNOP && isSecondInstrNOP)
return INCREMENTAL;
DCHECK(false);
return STORE_BUFFER_ONLY;
}
static void Patch(Code* stub, Mode mode) { static void Patch(Code* stub, Mode mode);
MacroAssembler masm(stub->GetIsolate(), stub->instruction_start(),
stub->instruction_size(), CodeObjectRequired::kNo);
// Get instruction lengths of two branches
int32_t first_instr_length = masm.instr_length_at(0);
int32_t second_instr_length = masm.instr_length_at(first_instr_length);
switch (mode) {
case STORE_BUFFER_ONLY:
DCHECK(GetMode(stub) == INCREMENTAL ||
GetMode(stub) == INCREMENTAL_COMPACTION);
PatchBranchCondMask(&masm, 0, CC_NOP);
PatchBranchCondMask(&masm, first_instr_length, CC_NOP);
break;
case INCREMENTAL:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchBranchCondMask(&masm, 0, CC_ALWAYS);
break;
case INCREMENTAL_COMPACTION:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
PatchBranchCondMask(&masm, first_instr_length, CC_ALWAYS);
break;
}
DCHECK(GetMode(stub) == mode);
Assembler::FlushICache(stub->GetIsolate(), stub->instruction_start(),
first_instr_length + second_instr_length);
}
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
...@@ -243,9 +188,7 @@ class RecordWriteStub : public PlatformCodeStub { ...@@ -243,9 +188,7 @@ class RecordWriteStub : public PlatformCodeStub {
Mode mode); Mode mode);
void InformIncrementalMarker(MacroAssembler* masm); void InformIncrementalMarker(MacroAssembler* masm);
void Activate(Code* code) override { void Activate(Code* code) override;
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
Register object() const { Register object() const {
return Register::from_code(ObjectBits::decode(minor_key_)); return Register::from_code(ObjectBits::decode(minor_key_));
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/assembler-inl.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/deoptimizer.h" #include "src/deoptimizer.h"
#include "src/register-configuration.h" #include "src/register-configuration.h"
......
...@@ -27,6 +27,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size, ...@@ -27,6 +27,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size,
CodeObjectRequired create_code_object) CodeObjectRequired create_code_object)
: TurboAssembler(isolate, buffer, size, create_code_object) {} : TurboAssembler(isolate, buffer, size, create_code_object) {}
TurboAssembler::TurboAssembler(Isolate* isolate, void* buffer, int buffer_size,
CodeObjectRequired create_code_object)
: Assembler(isolate, buffer, buffer_size), isolate_(isolate) {
if (create_code_object == CodeObjectRequired::kYes) {
code_object_ =
Handle<HeapObject>::New(isolate->heap()->undefined_value(), isolate);
}
}
int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode, int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion1, Register exclusion1,
Register exclusion2, Register exclusion2,
......
...@@ -165,13 +165,7 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg, ...@@ -165,13 +165,7 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
class TurboAssembler : public Assembler { class TurboAssembler : public Assembler {
public: public:
TurboAssembler(Isolate* isolate, void* buffer, int buffer_size, TurboAssembler(Isolate* isolate, void* buffer, int buffer_size,
CodeObjectRequired create_code_object) CodeObjectRequired create_code_object);
: Assembler(isolate, buffer, buffer_size), isolate_(isolate) {
if (create_code_object == CodeObjectRequired::kYes) {
code_object_ =
Handle<HeapObject>::New(isolate->heap()->undefined_value(), isolate);
}
}
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "test/unittests/compiler/instruction-selector-unittest.h" #include "test/unittests/compiler/instruction-selector-unittest.h"
#include "src/assembler-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler {} // namespace compiler namespace compiler {} // namespace compiler
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "test/unittests/compiler/instruction-selector-unittest.h" #include "test/unittests/compiler/instruction-selector-unittest.h"
#include "src/assembler-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler {} // namespace compiler namespace compiler {} // namespace compiler
......
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