Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(922)

Unified Diff: src/ppc/assembler-ppc.cc

Issue 1030353003: Enable constant pool support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/ppc/assembler-ppc.cc
diff --git a/src/ppc/assembler-ppc.cc b/src/ppc/assembler-ppc.cc
index 8889aa4b26da716f01f8be555c1a3e111123e94e..adf8cb82d1d40b872ef5c9d78f4e82c885e32b40 100644
--- a/src/ppc/assembler-ppc.cc
+++ b/src/ppc/assembler-ppc.cc
@@ -149,13 +149,18 @@ const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE |
bool RelocInfo::IsCodedSpecially() {
// The deserializer needs to know whether a pointer is specially
// coded. Being specially coded on PPC means that it is a lis/ori
- // instruction sequence, and these are always the case inside code
- // objects.
+ // instruction sequence or is an out of line constant pool entry,
+ // and these are always the case inside code objects.
return true;
}
bool RelocInfo::IsInConstantPool() {
+ if (FLAG_enable_embedded_constant_pool) {
+ Address constant_pool = host_->constant_pool();
+ return (constant_pool &&
+ (pc_ >= constant_pool || Assembler::IsConstantPoolLoadStart(pc_)));
+ }
return false;
}
@@ -202,11 +207,13 @@ MemOperand::MemOperand(Register ra, Register rb) {
Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
: AssemblerBase(isolate, buffer, buffer_size),
recorded_ast_id_(TypeFeedbackId::None()),
+ constant_pool_builder_(),
positions_recorder_(this) {
reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
no_trampoline_pool_before_ = 0;
trampoline_pool_blocked_nesting_ = 0;
+ constant_pool_entry_sharing_blocked_nesting_ = 0;
// We leave space (kMaxBlockTrampolineSectionSize)
// for BlockTrampolinePoolScope buffer.
next_buffer_check_ =
@@ -222,6 +229,9 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) {
+ // Emit constant pool if necessary.
+ int offset = EmitConstantPool();
+
EmitRelocations();
// Set up code descriptor.
@@ -229,6 +239,7 @@ void Assembler::GetCode(CodeDesc* desc) {
desc->buffer_size = buffer_size_;
desc->instr_size = pc_offset();
desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
+ desc->constant_pool_size = (offset ? desc->instr_size - offset : 0);
desc->origin = this;
}
@@ -472,7 +483,8 @@ void Assembler::target_at_put(int pos, int target_pos) {
// Load the address of the label in a register.
Register dst = Register::from_code(instr_at(pos + kInstrSize));
CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
- kMovInstructions, CodePatcher::DONT_FLUSH);
+ kMovInstructionsNoConstantPool,
+ CodePatcher::DONT_FLUSH);
// Keep internal references relative until EmitRelocations.
patcher.masm()->bitwise_mov(dst, target_pos);
break;
@@ -1500,6 +1512,38 @@ void Assembler::function_descriptor() {
}
+int Assembler::instructions_required_for_mov(const Operand& x) const {
+ bool canOptimize =
+ !(x.must_output_reloc_info(this) || is_trampoline_pool_blocked());
+ if (use_constant_pool_for_mov(x, canOptimize)) {
+ // Current usage guarantees that all constant pool references can
+ // use the same sequence.
+ return kMovInstructionsConstantPool;
+ }
+ DCHECK(!canOptimize);
+ return kMovInstructionsNoConstantPool;
+}
+
+
+bool Assembler::use_constant_pool_for_mov(const Operand& x,
+ bool canOptimize) const {
+ if (!FLAG_enable_embedded_constant_pool || !is_constant_pool_available() ||
+ is_constant_pool_full()) {
+ // If there is no constant pool available, we must use a mov
+ // immediate sequence.
+ return false;
+ }
+
+ intptr_t value = x.immediate();
+ if (canOptimize && is_int16(value)) {
+ // Prefer a single-instruction load-immediate.
+ return false;
+ }
+
+ return true;
+}
+
+
void Assembler::EnsureSpaceFor(int space_needed) {
if (buffer_space() <= (kGap + space_needed)) {
GrowBuffer(space_needed);
@@ -1532,6 +1576,20 @@ void Assembler::mov(Register dst, const Operand& src) {
canOptimize =
!(relocatable || (is_trampoline_pool_blocked() && !is_int16(value)));
+ if (use_constant_pool_for_mov(src, canOptimize)) {
+ DCHECK(is_constant_pool_available());
+ if (relocatable) {
+ RecordRelocInfo(src.rmode_);
+ }
+ ConstantPoolAddEntry(src.rmode_, value);
+#if V8_TARGET_ARCH_PPC64
+ ld(dst, MemOperand(kConstantPoolRegister, 0));
+#else
+ lwz(dst, MemOperand(kConstantPoolRegister, 0));
+#endif
+ return;
+ }
+
if (canOptimize) {
if (is_int16(value)) {
li(dst, Operand(value));
@@ -1673,6 +1731,7 @@ void Assembler::add_label_offset(Register dst, Register base, Label* label,
}
+// TODO(mbrandy): allow loading internal reference from constant pool
void Assembler::mov_label_addr(Register dst, Label* label) {
CheckBuffer();
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
@@ -1697,8 +1756,8 @@ void Assembler::mov_label_addr(Register dst, Label* label) {
BlockTrampolinePoolScope block_trampoline_pool(this);
emit(kUnboundMovLabelAddrOpcode | (link & kImm26Mask));
emit(dst.code());
- DCHECK(kMovInstructions >= 2);
- for (int i = 0; i < kMovInstructions - 2; i++) nop();
+ DCHECK(kMovInstructionsNoConstantPool >= 2);
+ for (int i = 0; i < kMovInstructionsNoConstantPool - 2; i++) nop();
}
}
@@ -2380,13 +2439,111 @@ void Assembler::CheckTrampolinePool() {
Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
- DCHECK(!FLAG_enable_ool_constant_pool);
+ UNREACHABLE();
return isolate->factory()->empty_constant_pool_array();
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
- DCHECK(!FLAG_enable_ool_constant_pool);
+ UNREACHABLE();
+}
+
+
+ConstantPoolBuilder::ConstantPoolBuilder() : size_(0) { entries_.reserve(64); }
+
+
+void ConstantPoolBuilder::AddEntry(ConstantPoolEntry& entry, bool sharing_ok) {
+ DCHECK(!IsEmitted());
+
+ if (sharing_ok) {
+ // Try to merge entries
+ size_t i;
+ std::vector<ConstantPoolEntry>::const_iterator it;
+ for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
+ if (it->merged_index_ != -2 && entry.IsEqual(*it)) {
+ // Merge with found entry.
+ entry.merged_index_ = i;
+ break;
+ }
+ }
+ } else {
+ // Ensure this entry remains unique
+ entry.merged_index_ = -2;
+ }
+
+ entries_.push_back(entry);
+
+ if (entry.merged_index_ < 0) {
+ // Not merged, so update the appropriate count and size.
+ number_of_entries_.increment(entry.type());
+ size_ = number_of_entries_.size();
+ }
+}
+
+
+void ConstantPoolBuilder::EmitGroup(Assembler* assm, int entrySize) {
+ int base = label_.pos();
+ for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+ entry != entries_.end(); entry++) {
+#if !V8_TARGET_ARCH_PPC64
+ // Skip entries not in the requested group based on size.
+ if (entry->size() != entrySize) continue;
+#endif
+
+ // Update constant pool if necessary and get the entry's offset.
+ int offset;
+ if (entry->merged_index_ < 0) {
+ offset = assm->pc_offset() - base;
+ entry->merged_index_ = offset; // Stash offset for merged entries.
+#if V8_TARGET_ARCH_PPC64
+ assm->emit_ptr(entry->value_);
+#else
+ if (entrySize == kDoubleSize) {
+ assm->emit_double(entry->value64_);
+ } else {
+ assm->emit_ptr(entry->value_);
+ }
+#endif
+ } else {
+ DCHECK(entry->merged_index_ < (entry - entries_.begin()));
+ offset = entries_[entry->merged_index_].merged_index_;
+ }
+
+ // Patch load instruction with correct offset.
+ assm->SetConstantPoolOffset(entry->position_, offset);
+ }
+}
+
+
+// Emit and return position of pool. Zero implies no constant pool.
+int ConstantPoolBuilder::Emit(Assembler* assm) {
+ bool empty = IsEmpty();
+ bool emitted = IsEmitted();
+
+ if (!emitted) {
+ // Mark start of constant pool. Align if necessary.
+ if (!empty) assm->CodeTargetAlign();
+ assm->bind(&label_);
+ }
+
+ int position = empty ? 0 : label_.pos();
+
+ if (!(emitted || empty)) {
+// Emit in groups based on size. We don't support 32-bit
+// constants in 64-bit mode so the only non-pointer-sized entries
+// are doubles in 32-bit mode.
+#if !V8_TARGET_ARCH_PPC64
+ // Emit any doubles first for alignment purposes.
+ if (number_of_entries_.count_of(INT64)) {
+ EmitGroup(assm, kDoubleSize);
+ }
+#endif
+ EmitGroup(assm, kPointerSize);
+ DCHECK(position > 0);
+ DCHECK(assm->pc_offset() - position == size_);
+ }
+
+ return position;
}
}
} // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698