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 @@
#if V8_TARGET_ARCH_PPC
#include "src/assembler-inl.h"
#include "src/codegen.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
......@@ -1405,7 +1406,7 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
__ mov(scratch0,
Operand(ExternalReference::builtins_address(masm->isolate())));
__ 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
// the case iff it does not equal DeserializeLazy.
......
......@@ -4,6 +4,7 @@
#if V8_TARGET_ARCH_S390
#include "src/assembler-inl.h"
#include "src/codegen.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
......
......@@ -4,6 +4,8 @@
#include "src/compiler/code-generator.h"
#include "src/assembler-inl.h"
#include "src/callable.h"
#include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
......
......@@ -4,6 +4,8 @@
#include "src/compiler/code-generator.h"
#include "src/assembler-inl.h"
#include "src/callable.h"
#include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
......
......@@ -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) {}
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() {
DCHECK(!trampoline_emitted_);
DCHECK(tracked_branch_count_ > 0);
......@@ -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
Address Assembler::target_address_at(Address pc, Address constant_pool) {
if (FLAG_enable_embedded_constant_pool && constant_pool) {
......
......@@ -383,12 +383,19 @@ class Operand BASE_EMBEDDED {
public:
// 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(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);
INLINE(explicit Operand(Smi* value));
INLINE(explicit Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR)) {
value_.immediate = reinterpret_cast<intptr_t>(value);
}
// rm
INLINE(explicit Operand(Register rm));
......@@ -396,7 +403,7 @@ class Operand BASE_EMBEDDED {
static Operand EmbeddedCode(CodeStub* stub);
// 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;
......@@ -1533,13 +1540,39 @@ class Assembler : public AssemblerBase {
ConstantPoolBuilder constant_pool_builder_;
// Code emission
inline void CheckBuffer();
void CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
void GrowBuffer(int needed = 0);
inline void emit(Instr x);
inline void TrackBranch();
// Code emission
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 CheckTrampolinePoolQuick();
void CheckTrampolinePoolQuick() {
if (pc_offset() >= next_trampoline_check_) {
CheckTrampolinePool();
}
}
// Instruction generation
void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
......
......@@ -5,6 +5,7 @@
#if V8_TARGET_ARCH_PPC
#include "src/api-arguments.h"
#include "src/assembler-inl.h"
#include "src/base/bits.h"
#include "src/bootstrapper.h"
#include "src/code-stubs.h"
......@@ -1007,6 +1008,49 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
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
// the value has just been written into the object, now this stub makes sure
......@@ -1097,6 +1141,9 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode());
}
void RecordWriteStub::Activate(Code* code) {
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
......
......@@ -94,49 +94,9 @@ class RecordWriteStub : public PlatformCodeStub {
masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BF);
}
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 Mode GetMode(Code* stub);
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);
}
static void Patch(Code* stub, Mode mode);
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
......@@ -216,9 +176,7 @@ class RecordWriteStub : public PlatformCodeStub {
Mode mode);
void InformIncrementalMarker(MacroAssembler* masm);
void Activate(Code* code) override {
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
void Activate(Code* code) override;
Register object() const {
return Register::from_code(ObjectBits::decode(minor_key_));
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/assembler-inl.h"
#include "src/codegen.h"
#include "src/deoptimizer.h"
#include "src/register-configuration.h"
......
......@@ -27,6 +27,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size,
CodeObjectRequired 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,
Register exclusion1,
Register exclusion2,
......
......@@ -108,13 +108,8 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
class TurboAssembler : public Assembler {
public:
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);
}
}
CodeObjectRequired create_code_object);
void set_has_frame(bool value) { has_frame_ = value; }
bool has_frame() { return has_frame_; }
......
......@@ -6,6 +6,7 @@
#include "src/regexp/ppc/regexp-macro-assembler-ppc.h"
#include "src/assembler-inl.h"
#include "src/base/bits.h"
#include "src/code-stubs.h"
#include "src/log.h"
......
......@@ -6,6 +6,7 @@
#if V8_TARGET_ARCH_S390
#include "src/assembler-inl.h"
#include "src/base/bits.h"
#include "src/code-stubs.h"
#include "src/log.h"
......
......@@ -233,27 +233,8 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
}
// 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) {}
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
int32_t Assembler::emit_code_target(Handle<Code> target,
RelocInfo::Mode rmode) {
DCHECK(RelocInfo::IsCodeTarget(rmode));
......@@ -270,60 +251,6 @@ int32_t Assembler::emit_code_target(Handle<Code> target,
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
Address Assembler::target_address_at(Address pc, Address constant_pool) {
......
......@@ -368,11 +368,19 @@ class Operand BASE_EMBEDDED {
public:
// 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(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);
INLINE(explicit Operand(Smi* value));
INLINE(explicit Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR)) {
value_.immediate = reinterpret_cast<intptr_t>(value);
}
// rm
INLINE(explicit Operand(Register rm));
......@@ -380,7 +388,7 @@ class Operand BASE_EMBEDDED {
static Operand EmbeddedNumber(double value); // Smi or HeapNumber
// 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;
......@@ -1438,7 +1446,11 @@ class Assembler : public AssemblerBase {
int last_bound_pos_;
// Code emission
inline void CheckBuffer();
void CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
void GrowBuffer(int needed = 0);
inline void TrackBranch();
inline void UntrackBranch();
......@@ -1446,10 +1458,58 @@ class Assembler : public AssemblerBase {
inline int32_t emit_code_target(
Handle<Code> target, RelocInfo::Mode rmode);
// Helpers to emit binary encoding of 2/4/6 byte instructions.
inline void emit2bytes(uint16_t x);
inline void emit4bytes(uint32_t x);
inline void emit6bytes(uint64_t x);
// Helper to emit the binary encoding of a 2 byte instruction
void 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 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.
......
......@@ -5,6 +5,7 @@
#if V8_TARGET_ARCH_S390
#include "src/api-arguments.h"
#include "src/assembler-inl.h"
#include "src/base/bits.h"
#include "src/bootstrapper.h"
#include "src/code-stubs.h"
......@@ -986,6 +987,64 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
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
// the value has just been written into the object, now this stub makes sure
......@@ -1073,6 +1132,10 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode());
}
void RecordWriteStub::Activate(Code* code) {
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
Mode mode) {
......
......@@ -108,64 +108,9 @@ class RecordWriteStub : public PlatformCodeStub {
return false;
}
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 Mode GetMode(Code* stub);
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);
}
static void Patch(Code* stub, Mode mode);
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
......@@ -243,9 +188,7 @@ class RecordWriteStub : public PlatformCodeStub {
Mode mode);
void InformIncrementalMarker(MacroAssembler* masm);
void Activate(Code* code) override {
code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
}
void Activate(Code* code) override;
Register object() const {
return Register::from_code(ObjectBits::decode(minor_key_));
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/assembler-inl.h"
#include "src/codegen.h"
#include "src/deoptimizer.h"
#include "src/register-configuration.h"
......
......@@ -27,6 +27,15 @@ MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size,
CodeObjectRequired 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,
Register exclusion1,
Register exclusion2,
......
......@@ -165,13 +165,7 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
class TurboAssembler : public Assembler {
public:
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);
}
}
CodeObjectRequired create_code_object);
Isolate* isolate() const { return isolate_; }
......
......@@ -4,6 +4,8 @@
#include "test/unittests/compiler/instruction-selector-unittest.h"
#include "src/assembler-inl.h"
namespace v8 {
namespace internal {
namespace compiler {} // namespace compiler
......
......@@ -4,6 +4,8 @@
#include "test/unittests/compiler/instruction-selector-unittest.h"
#include "src/assembler-inl.h"
namespace v8 {
namespace internal {
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