| Index: src/ppc/assembler-ppc.h
|
| diff --git a/src/ppc/assembler-ppc.h b/src/ppc/assembler-ppc.h
|
| index bcc2d8f6b627c6157f233187d81d56fd7550cdb5..fb56852bb5b5c254d82662f910f0b1c5265f90dc 100644
|
| --- a/src/ppc/assembler-ppc.h
|
| +++ b/src/ppc/assembler-ppc.h
|
| @@ -108,7 +108,8 @@ struct Register {
|
| static const int kAllocatableLowRangeBegin = 3;
|
| static const int kAllocatableLowRangeEnd = 10;
|
| static const int kAllocatableHighRangeBegin = 14;
|
| - static const int kAllocatableHighRangeEnd = 28;
|
| + static const int kAllocatableHighRangeEnd =
|
| + FLAG_enable_embedded_constant_pool ? 27 : 28;
|
| static const int kAllocatableContext = 30;
|
|
|
| static const int kNumAllocatableLow =
|
| @@ -177,6 +178,10 @@ struct Register {
|
| "r28",
|
| "cp",
|
| };
|
| + if (FLAG_enable_embedded_constant_pool &&
|
| + (index == kMaxNumAllocatableRegisters - 2)) {
|
| + return names[index + 1];
|
| + }
|
| return names[index];
|
| }
|
|
|
| @@ -184,7 +189,7 @@ struct Register {
|
| 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 |
|
| 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 |
|
| 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 |
|
| - 1 << 28 | 1 << 30;
|
| + (FLAG_enable_embedded_constant_pool ? 0 : 1 << 28) | 1 << 30;
|
|
|
| static Register from_code(int code) {
|
| Register r = {code};
|
| @@ -242,7 +247,7 @@ const int kRegister_r24_Code = 24;
|
| const int kRegister_r25_Code = 25;
|
| const int kRegister_r26_Code = 26;
|
| const int kRegister_r27_Code = 27;
|
| -const int kRegister_r28_Code = 28;
|
| +const int kRegister_r28_Code = 28; // constant pool pointer
|
| const int kRegister_r29_Code = 29; // roots array pointer
|
| const int kRegister_r30_Code = 30; // context pointer
|
| const int kRegister_fp_Code = 31; // frame pointer
|
| @@ -286,6 +291,7 @@ const Register fp = {kRegister_fp_Code};
|
| // Give alias names to registers
|
| const Register cp = {kRegister_r30_Code}; // JavaScript context pointer
|
| const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer.
|
| +const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool
|
|
|
| // Double word FP register.
|
| struct DoubleRegister {
|
| @@ -595,20 +601,36 @@ class Assembler : public AssemblerBase {
|
| // The high 8 bits are set to zero.
|
| void label_at_put(Label* L, int at_offset);
|
|
|
| + INLINE(static bool IsConstantPoolLoadStart(
|
| + Address pc, ConstantPoolEntry::Access* access = nullptr));
|
| + INLINE(static bool IsConstantPoolLoadEnd(
|
| + Address pc, ConstantPoolEntry::Access* access = nullptr));
|
| + INLINE(static int GetConstantPoolOffset(Address pc,
|
| + ConstantPoolEntry::Access access,
|
| + ConstantPoolEntry::Type type));
|
| + INLINE(void PatchConstantPoolAccessInstruction(
|
| + int pc_offset, int offset, ConstantPoolEntry::Access access,
|
| + ConstantPoolEntry::Type type));
|
| +
|
| + // Return the address in the constant pool of the code target address used by
|
| + // the branch/call instruction at pc, or the object in a mov.
|
| + INLINE(static Address target_constant_pool_address_at(
|
| + Address pc, Address constant_pool, ConstantPoolEntry::Access access,
|
| + ConstantPoolEntry::Type type));
|
| +
|
| // Read/Modify the code target address in the branch/call instruction at pc.
|
| - INLINE(static Address target_address_at(Address pc,
|
| - ConstantPoolArray* constant_pool));
|
| + INLINE(static Address target_address_at(Address pc, Address constant_pool));
|
| INLINE(static void set_target_address_at(
|
| - Address pc, ConstantPoolArray* constant_pool, Address target,
|
| + Address pc, Address constant_pool, Address target,
|
| ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
|
| INLINE(static Address target_address_at(Address pc, Code* code)) {
|
| - ConstantPoolArray* constant_pool = NULL;
|
| + Address constant_pool = code ? code->constant_pool() : NULL;
|
| return target_address_at(pc, constant_pool);
|
| }
|
| INLINE(static void set_target_address_at(
|
| Address pc, Code* code, Address target,
|
| ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
|
| - ConstantPoolArray* constant_pool = NULL;
|
| + Address constant_pool = code ? code->constant_pool() : NULL;
|
| set_target_address_at(pc, constant_pool, target, icache_flush_mode);
|
| }
|
|
|
| @@ -646,12 +668,21 @@ class Assembler : public AssemblerBase {
|
|
|
| // Number of instructions to load an address via a mov sequence.
|
| #if V8_TARGET_ARCH_PPC64
|
| - static const int kMovInstructions = 5;
|
| + static const int kMovInstructionsConstantPool = 1;
|
| + static const int kMovInstructionsNoConstantPool = 5;
|
| +#if defined(V8_PPC_TAGGING_OPT)
|
| + static const int kTaggedLoadInstructions = 1;
|
| +#else
|
| static const int kTaggedLoadInstructions = 2;
|
| +#endif
|
| #else
|
| - static const int kMovInstructions = 2;
|
| + static const int kMovInstructionsConstantPool = 1;
|
| + static const int kMovInstructionsNoConstantPool = 2;
|
| static const int kTaggedLoadInstructions = 1;
|
| #endif
|
| + static const int kMovInstructions = FLAG_enable_embedded_constant_pool
|
| + ? kMovInstructionsConstantPool
|
| + : kMovInstructionsNoConstantPool;
|
|
|
| // Distance between the instruction referring to the address of the call
|
| // target and the return address.
|
| @@ -682,13 +713,15 @@ class Assembler : public AssemblerBase {
|
|
|
| // This is the length of the BreakLocation::SetDebugBreakAtReturn()
|
| // code patch FIXED_SEQUENCE
|
| - static const int kJSReturnSequenceInstructions = kMovInstructions + 3;
|
| + static const int kJSReturnSequenceInstructions =
|
| + kMovInstructionsNoConstantPool + 3;
|
| static const int kJSReturnSequenceLength =
|
| kJSReturnSequenceInstructions * kInstrSize;
|
|
|
| // This is the length of the code sequence from SetDebugBreakAtSlot()
|
| // FIXED_SEQUENCE
|
| - static const int kDebugBreakSlotInstructions = kMovInstructions + 2;
|
| + static const int kDebugBreakSlotInstructions =
|
| + kMovInstructionsNoConstantPool + 2;
|
| static const int kDebugBreakSlotLength =
|
| kDebugBreakSlotInstructions * kInstrSize;
|
|
|
| @@ -1201,6 +1234,23 @@ class Assembler : public AssemblerBase {
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
|
| };
|
|
|
| + // Class for scoping disabling constant pool entry merging
|
| + class BlockConstantPoolEntrySharingScope {
|
| + public:
|
| + explicit BlockConstantPoolEntrySharingScope(Assembler* assem)
|
| + : assem_(assem) {
|
| + assem_->StartBlockConstantPoolEntrySharing();
|
| + }
|
| + ~BlockConstantPoolEntrySharingScope() {
|
| + assem_->EndBlockConstantPoolEntrySharing();
|
| + }
|
| +
|
| + private:
|
| + Assembler* assem_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope);
|
| + };
|
| +
|
| // Debugging
|
|
|
| // Mark address of the ExitJSFrame code.
|
| @@ -1237,8 +1287,8 @@ class Assembler : public AssemblerBase {
|
| // for inline tables, e.g., jump-tables.
|
| void db(uint8_t data);
|
| void dd(uint32_t data);
|
| - void emit_ptr(intptr_t data);
|
| - void emit_double(double data);
|
| + void dq(uint64_t data);
|
| + void dp(uintptr_t data);
|
|
|
| PositionsRecorder* positions_recorder() { return &positions_recorder_; }
|
|
|
| @@ -1284,6 +1334,19 @@ class Assembler : public AssemblerBase {
|
| void BlockTrampolinePoolFor(int instructions);
|
| void CheckTrampolinePool();
|
|
|
| + // For mov. Return the number of actual instructions required to
|
| + // load the operand into a register. This can be anywhere from
|
| + // one (constant pool small section) to five instructions (full
|
| + // 64-bit sequence).
|
| + //
|
| + // The value returned is only valid as long as no entries are added to the
|
| + // constant pool between this call and the actual instruction being emitted.
|
| + int instructions_required_for_mov(Register dst, const Operand& src) const;
|
| +
|
| + // Decide between using the constant pool vs. a mov immediate sequence.
|
| + bool use_constant_pool_for_mov(Register dst, const Operand& src,
|
| + bool canOptimize) const;
|
| +
|
| // The code currently calls CheckBuffer() too often. This has the side
|
| // effect of randomly growing the buffer in the middle of multi-instruction
|
| // sequences.
|
| @@ -1291,11 +1354,16 @@ class Assembler : public AssemblerBase {
|
| // This function allows outside callers to check and grow the buffer
|
| void EnsureSpaceFor(int space_needed);
|
|
|
| - // Allocate a constant pool of the correct size for the generated code.
|
| - Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
|
| + int EmitConstantPool() { return constant_pool_builder_.Emit(this); }
|
|
|
| - // Generate the constant pool for the generated code.
|
| - void PopulateConstantPool(ConstantPoolArray* constant_pool);
|
| + bool ConstantPoolAccessIsInOverflow() const {
|
| + return constant_pool_builder_.NextAccess(ConstantPoolEntry::INTPTR) ==
|
| + ConstantPoolEntry::OVERFLOWED;
|
| + }
|
| +
|
| + Label* ConstantPoolPosition() {
|
| + return constant_pool_builder_.EmittedPosition();
|
| + }
|
|
|
| void EmitRelocations();
|
|
|
| @@ -1315,7 +1383,16 @@ class Assembler : public AssemblerBase {
|
|
|
| // Record reloc info for current pc_
|
| void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
|
| - void RecordRelocInfo(const DeferredRelocInfo& rinfo);
|
| + ConstantPoolEntry::Access ConstantPoolAddEntry(RelocInfo::Mode rmode,
|
| + intptr_t value) {
|
| + bool sharing_ok = RelocInfo::IsNone(rmode) ||
|
| + !(serializer_enabled() || rmode < RelocInfo::CELL ||
|
| + is_constant_pool_entry_sharing_blocked());
|
| + return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok);
|
| + }
|
| + ConstantPoolEntry::Access ConstantPoolAddEntry(double value) {
|
| + return constant_pool_builder_.AddEntry(pc_offset(), value);
|
| + }
|
|
|
| // Block the emission of the trampoline pool before pc_offset.
|
| void BlockTrampolinePoolBefore(int pc_offset) {
|
| @@ -1329,6 +1406,16 @@ class Assembler : public AssemblerBase {
|
| return trampoline_pool_blocked_nesting_ > 0;
|
| }
|
|
|
| + void StartBlockConstantPoolEntrySharing() {
|
| + constant_pool_entry_sharing_blocked_nesting_++;
|
| + }
|
| + void EndBlockConstantPoolEntrySharing() {
|
| + constant_pool_entry_sharing_blocked_nesting_--;
|
| + }
|
| + bool is_constant_pool_entry_sharing_blocked() const {
|
| + return constant_pool_entry_sharing_blocked_nesting_ > 0;
|
| + }
|
| +
|
| bool has_exception() const { return internal_trampoline_exception_; }
|
|
|
| bool is_trampoline_emitted() const { return trampoline_emitted_; }
|
| @@ -1350,6 +1437,9 @@ class Assembler : public AssemblerBase {
|
| int trampoline_pool_blocked_nesting_; // Block emission if this is not zero.
|
| int no_trampoline_pool_before_; // Block emission before this pc offset.
|
|
|
| + // Do not share constant pool entries.
|
| + int constant_pool_entry_sharing_blocked_nesting_;
|
| +
|
| // Relocation info generation
|
| // Each relocation is encoded as a variable size value
|
| static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
|
| @@ -1359,6 +1449,8 @@ class Assembler : public AssemblerBase {
|
| // The bound position, before this we cannot do instruction elimination.
|
| int last_bound_pos_;
|
|
|
| + ConstantPoolBuilder constant_pool_builder_;
|
| +
|
| // Code emission
|
| inline void CheckBuffer();
|
| void GrowBuffer(int needed = 0);
|
|
|