Index: src/assembler.h |
diff --git a/src/assembler.h b/src/assembler.h |
index d5822395b954acf34144d43c8128e16c926f7d45..2bad1eb7492f84b6287777aa729f68439f896803 100644 |
--- a/src/assembler.h |
+++ b/src/assembler.h |
@@ -79,11 +79,11 @@ class AssemblerBase: public Malloced { |
return (enabled_cpu_features_ & (static_cast<uint64_t>(1) << f)) != 0; |
} |
- bool is_ool_constant_pool_available() const { |
- if (FLAG_enable_ool_constant_pool) { |
- return ool_constant_pool_available_; |
+ bool is_constant_pool_available() const { |
+ if (FLAG_enable_embedded_constant_pool) { |
+ return constant_pool_available_; |
} else { |
- // Out-of-line constant pool not supported on this architecture. |
+ // Embedded constant pool not supported on this architecture. |
UNREACHABLE(); |
return false; |
} |
@@ -108,11 +108,11 @@ class AssemblerBase: public Malloced { |
int buffer_size_; |
bool own_buffer_; |
- void set_ool_constant_pool_available(bool available) { |
- if (FLAG_enable_ool_constant_pool) { |
- ool_constant_pool_available_ = available; |
+ void set_constant_pool_available(bool available) { |
+ if (FLAG_enable_embedded_constant_pool) { |
+ constant_pool_available_ = available; |
} else { |
- // Out-of-line constant pool not supported on this architecture. |
+ // Embedded constant pool not supported on this architecture. |
UNREACHABLE(); |
} |
} |
@@ -130,7 +130,7 @@ class AssemblerBase: public Malloced { |
// Indicates whether the constant pool can be accessed, which is only possible |
// if the pp register points to the current code object's constant pool. |
- bool ool_constant_pool_available_; |
+ bool constant_pool_available_; |
// Constant pool. |
friend class FrameAndConstantPoolScope; |
@@ -413,9 +413,6 @@ class RelocInfo { |
RelocInfo(byte* pc, Mode rmode, intptr_t data, Code* host) |
: pc_(pc), rmode_(rmode), data_(data), host_(host) { |
} |
- RelocInfo(byte* pc, double data64) |
- : pc_(pc), rmode_(NONE64), data64_(data64), host_(NULL) { |
- } |
static inline bool IsRealRelocMode(Mode mode) { |
return mode >= FIRST_REAL_RELOC_MODE && |
@@ -487,22 +484,11 @@ class RelocInfo { |
} |
static inline int ModeMask(Mode mode) { return 1 << mode; } |
- // Returns true if the first RelocInfo has the same mode and raw data as the |
- // second one. |
- static inline bool IsEqual(RelocInfo first, RelocInfo second) { |
- return first.rmode() == second.rmode() && |
- (first.rmode() == RelocInfo::NONE64 ? |
- first.raw_data64() == second.raw_data64() : |
- first.data() == second.data()); |
- } |
- |
// Accessors |
byte* pc() const { return pc_; } |
void set_pc(byte* pc) { pc_ = pc; } |
Mode rmode() const { return rmode_; } |
intptr_t data() const { return data_; } |
- double data64() const { return data64_; } |
- uint64_t raw_data64() { return bit_cast<uint64_t>(data64_); } |
Code* host() const { return host_; } |
void set_host(Code* host) { host_ = host; } |
@@ -645,10 +631,7 @@ class RelocInfo { |
// comment). |
byte* pc_; |
Mode rmode_; |
- union { |
- intptr_t data_; |
- double data64_; |
- }; |
+ intptr_t data_; |
Code* host_; |
// External-reference pointers are also split across instruction-pairs |
// on some platforms, but are accessed via indirect pointers. This location |
@@ -1171,6 +1154,126 @@ class NullCallWrapper : public CallWrapper { |
}; |
+// ----------------------------------------------------------------------------- |
+// Constant pool support |
+ |
+class ConstantPoolEntry { |
+ public: |
+ ConstantPoolEntry() {} |
+ ConstantPoolEntry(int position, intptr_t value, bool sharing_ok) |
+ : position_(position), |
+ merged_index_(sharing_ok ? SHARING_ALLOWED : SHARING_PROHIBITED), |
+ value_(value) {} |
+ ConstantPoolEntry(int position, double value) |
+ : position_(position), merged_index_(SHARING_ALLOWED), value64_(value) {} |
+ |
+ int position() const { return position_; } |
+ bool sharing_ok() const { return merged_index_ != SHARING_PROHIBITED; } |
+ bool is_merged() const { return merged_index_ >= 0; } |
+ int merged_index(void) const { |
+ DCHECK(is_merged()); |
+ return merged_index_; |
+ } |
+ void set_merged_index(int index) { |
+ merged_index_ = index; |
+ DCHECK(is_merged()); |
+ } |
+ int offset(void) const { |
+ DCHECK(merged_index_ >= 0); |
+ return merged_index_; |
+ } |
+ void set_offset(int offset) { |
+ DCHECK(offset >= 0); |
+ merged_index_ = offset; |
+ } |
+ intptr_t value() const { return value_; } |
+ uint64_t value64() const { return bit_cast<uint64_t>(value64_); } |
+ |
+ enum Type { INTPTR, DOUBLE, NUMBER_OF_TYPES }; |
+ |
+ static int size(Type type) { |
+ return (type == INTPTR) ? kPointerSize : kDoubleSize; |
+ } |
+ |
+ enum Access { REGULAR, OVERFLOWED }; |
+ |
+ private: |
+ int position_; |
+ int merged_index_; |
+ union { |
+ intptr_t value_; |
+ double value64_; |
+ }; |
+ enum { SHARING_PROHIBITED = -2, SHARING_ALLOWED = -1 }; |
+}; |
+ |
+ |
+// ----------------------------------------------------------------------------- |
+// Embedded constant pool support |
+ |
+class ConstantPoolBuilder BASE_EMBEDDED { |
+ public: |
+ ConstantPoolBuilder(int ptr_reach_bits, int double_reach_bits); |
+ |
+ // Add pointer-sized constant to the embedded constant pool |
+ ConstantPoolEntry::Access AddEntry(int position, intptr_t value, |
+ bool sharing_ok) { |
+ ConstantPoolEntry entry(position, value, sharing_ok); |
+ return AddEntry(entry, ConstantPoolEntry::INTPTR); |
+ } |
+ |
+ // Add double constant to the embedded constant pool |
+ ConstantPoolEntry::Access AddEntry(int position, double value) { |
+ ConstantPoolEntry entry(position, value); |
+ return AddEntry(entry, ConstantPoolEntry::DOUBLE); |
+ } |
+ |
+ // Previews the access type required for the next new entry to be added. |
+ ConstantPoolEntry::Access NextAccess(ConstantPoolEntry::Type type) const; |
+ |
+ bool IsEmpty() { |
+ return info_[ConstantPoolEntry::INTPTR].entries.empty() && |
+ info_[ConstantPoolEntry::INTPTR].shared_entries.empty() && |
+ info_[ConstantPoolEntry::DOUBLE].entries.empty() && |
+ info_[ConstantPoolEntry::DOUBLE].shared_entries.empty(); |
+ } |
+ |
+ // Emit the constant pool. Invoke only after all entries have been |
+ // added and all instructions have been emitted. |
+ // Returns position of the emitted pool (zero implies no constant pool). |
+ int Emit(Assembler* assm); |
+ |
+ // Returns the label associated with the start of the constant pool. |
+ // Linking to this label in the function prologue may provide an |
+ // efficient means of constant pool pointer register initialization |
+ // on some architectures. |
+ inline Label* EmittedPosition() { return &emitted_label_; } |
+ |
+ private: |
+ ConstantPoolEntry::Access AddEntry(ConstantPoolEntry& entry, |
+ ConstantPoolEntry::Type type); |
+ void EmitSharedEntries(Assembler* assm, ConstantPoolEntry::Type type); |
+ void EmitGroup(Assembler* assm, ConstantPoolEntry::Access access, |
+ ConstantPoolEntry::Type type); |
+ |
+ struct PerTypeEntryInfo { |
+ PerTypeEntryInfo() : regular_count(0), overflow_start(-1) {} |
+ bool overflow() const { |
+ return (overflow_start >= 0 && |
+ overflow_start < static_cast<int>(entries.size())); |
+ } |
+ int regular_reach_bits; |
+ int regular_count; |
+ int overflow_start; |
+ std::vector<ConstantPoolEntry> entries; |
+ std::vector<ConstantPoolEntry> shared_entries; |
+ }; |
+ |
+ Label emitted_label_; // Records pc_offset of emitted pool |
+ PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES]; |
+}; |
+ |
+ |
} } // namespace v8::internal |
#endif // V8_ASSEMBLER_H_ |