Clean up encoding of size and single entry flag in Instructions.

R=vegorov@google.com

Review URL: https://codereview.chromium.org/2490363002 .
This commit is contained in:
Regis Crelier 2016-11-11 11:09:37 -08:00
parent 61ab47bcef
commit 3bf6796440
6 changed files with 55 additions and 27 deletions

View file

@ -11385,7 +11385,8 @@ RawInstructions* Instructions::New(intptr_t size, bool has_single_entry_point) {
Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_size(has_single_entry_point ? size : -size);
result.SetSize(size);
result.SetHasSingleEntryPoint(has_single_entry_point);
}
return result.raw();
}
@ -13765,9 +13766,9 @@ void Code::Disassemble(DisassemblyFormatter* formatter) const {
const Instructions& instr = Instructions::Handle(instructions());
uword start = instr.PayloadStart();
if (formatter == NULL) {
Disassembler::Disassemble(start, start + instr.size(), *this);
Disassembler::Disassemble(start, start + instr.Size(), *this);
} else {
Disassembler::Disassemble(start, start + instr.size(), formatter, *this);
Disassembler::Disassemble(start, start + instr.Size(), formatter, *this);
}
#endif
}
@ -13996,14 +13997,14 @@ RawCode* Code::FinalizeCode(const char* name,
// Copy the instructions into the instruction area and apply all fixups.
// Embedded pointers are still in handles at this point.
MemoryRegion region(reinterpret_cast<void*>(instrs.PayloadStart()),
instrs.size());
instrs.Size());
assembler->FinalizeInstructions(region);
CPU::FlushICache(instrs.PayloadStart(), instrs.size());
CPU::FlushICache(instrs.PayloadStart(), instrs.Size());
code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
#ifndef PRODUCT
CodeObservers::NotifyAll(name, instrs.PayloadStart(),
assembler->prologue_offset(), instrs.size(),
assembler->prologue_offset(), instrs.Size(),
optimized);
#endif
{

View file

@ -4012,14 +4012,33 @@ class ObjectPool : public Object {
class Instructions : public Object {
public:
enum {
kSizePos = 0,
kSizeSize = 31,
kFlagsPos = kSizePos + kSizeSize,
kFlagsSize = 1, // Currently, only flag is single entry flag.
};
class SizeBits : public BitField<uint32_t, uint32_t, kSizePos, kSizeSize> {};
class FlagsBits : public BitField<uint32_t, bool, kFlagsPos, kFlagsSize> {};
// Excludes HeaderSize().
intptr_t size() const { return abs(raw_ptr()->size_); }
bool HasSingleEntryPoint() const { return raw_ptr()->size_ >= 0; }
intptr_t Size() const { return SizeBits::decode(raw_ptr()->size_and_flags_); }
static intptr_t Size(const RawInstructions* instr) {
return SizeBits::decode(instr->ptr()->size_and_flags_);
}
bool HasSingleEntryPoint() const {
return FlagsBits::decode(raw_ptr()->size_and_flags_);
}
static bool HasSingleEntryPoint(const RawInstructions* instr) {
return FlagsBits::decode(instr->ptr()->size_and_flags_);
}
uword PayloadStart() const { return PayloadStart(raw()); }
uword CheckedEntryPoint() const { return CheckedEntryPoint(raw()); }
uword UncheckedEntryPoint() const { return UncheckedEntryPoint(raw()); }
static uword PayloadStart(RawInstructions* instr) {
static uword PayloadStart(const RawInstructions* instr) {
return reinterpret_cast<uword>(instr->ptr()) + HeaderSize();
}
@ -4045,16 +4064,16 @@ class Instructions : public Object {
#error Missing entry offsets for current architecture
#endif
static uword CheckedEntryPoint(RawInstructions* instr) {
static uword CheckedEntryPoint(const RawInstructions* instr) {
uword entry = PayloadStart(instr);
if (instr->ptr()->size_ < 0) {
if (!HasSingleEntryPoint(instr)) {
entry += kCheckedEntryOffset;
}
return entry;
}
static uword UncheckedEntryPoint(RawInstructions* instr) {
static uword UncheckedEntryPoint(const RawInstructions* instr) {
uword entry = PayloadStart(instr);
if (instr->ptr()->size_ < 0) {
if (!HasSingleEntryPoint(instr)) {
entry += kUncheckedEntryOffset;
}
return entry;
@ -4089,16 +4108,23 @@ class Instructions : public Object {
}
bool Equals(const Instructions& other) const {
if (size() != other.size()) {
if (Size() != other.Size()) {
return false;
}
NoSafepointScope no_safepoint;
return memcmp(raw_ptr(), other.raw_ptr(), InstanceSize(size())) == 0;
return memcmp(raw_ptr(), other.raw_ptr(), InstanceSize(Size())) == 0;
}
private:
void set_size(intptr_t size) const {
StoreNonPointer(&raw_ptr()->size_, size);
void SetSize(intptr_t value) const {
ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->size_and_flags_,
SizeBits::update(value, raw_ptr()->size_and_flags_));
}
void SetHasSingleEntryPoint(bool value) const {
StoreNonPointer(&raw_ptr()->size_and_flags_,
FlagsBits::update(value, raw_ptr()->size_and_flags_));
}
// New is a private method as RawInstruction and RawCode objects should
@ -4573,13 +4599,13 @@ class Code : public Object {
}
intptr_t Size() const {
const Instructions& instr = Instructions::Handle(instructions());
return instr.size();
return instr.Size();
}
RawObjectPool* GetObjectPool() const { return object_pool(); }
bool ContainsInstructionAt(uword addr) const {
const Instructions& instr = Instructions::Handle(instructions());
const uword offset = addr - instr.PayloadStart();
return offset < static_cast<uword>(instr.size());
return offset < static_cast<uword>(instr.Size());
}
// Returns true if there is a debugger breakpoint set in this code object.

View file

@ -139,7 +139,7 @@ class InstructionsKeyValueTrait {
static Value ValueOf(Pair kv) { return kv; }
static inline intptr_t Hashcode(Key key) { return key->size(); }
static inline intptr_t Hashcode(Key key) { return key->Size(); }
static inline bool IsKeyEqual(Pair pair, Key key) {
return pair->Equals(*key);

View file

@ -68,7 +68,7 @@ intptr_t RawObject::SizeFromClass() const {
case kInstructionsCid: {
const RawInstructions* raw_instructions =
reinterpret_cast<const RawInstructions*>(this);
intptr_t instructions_size = abs(raw_instructions->ptr()->size_);
intptr_t instructions_size = Instructions::Size(raw_instructions);
instance_size = Instructions::InstanceSize(instructions_size);
break;
}
@ -580,15 +580,14 @@ intptr_t RawObjectPool::VisitObjectPoolPointers(RawObjectPool* raw_obj,
intptr_t RawInstructions::VisitInstructionsPointers(
RawInstructions* raw_obj,
ObjectPointerVisitor* visitor) {
RawInstructions* obj = raw_obj->ptr();
return Instructions::InstanceSize(abs(obj->size_));
return Instructions::InstanceSize(Instructions::Size(raw_obj));
}
bool RawInstructions::ContainsPC(RawInstructions* raw_instr, uword pc) {
uword start_pc =
reinterpret_cast<uword>(raw_instr->ptr()) + Instructions::HeaderSize();
uword end_pc = start_pc + abs(raw_instr->ptr()->size_);
uword end_pc = start_pc + Instructions::Size(raw_instr);
ASSERT(end_pc > start_pc);
return (pc >= start_pc) && (pc < end_pc);
}

View file

@ -1161,7 +1161,9 @@ class RawObjectPool : public RawObject {
class RawInstructions : public RawObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Instructions);
int32_t size_;
// Instructions size in bytes and flags.
// Currently, only flag indicates 1 or 2 entry points.
uint32_t size_and_flags_;
// Variable length data follows here.
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }

View file

@ -814,7 +814,7 @@ void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer,
NoSafepointScope no_safepoint;
uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag;
uword entry = beginning + Instructions::HeaderSize();
uword payload_size = insns.size();
uword payload_size = insns.Size();
payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment());
uword end = entry + payload_size;
@ -945,7 +945,7 @@ void BlobInstructionsWriter::Write(uint8_t* vmisolate_buffer,
NoSafepointScope no_safepoint;
uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag;
uword entry = beginning + Instructions::HeaderSize();
uword payload_size = insns.size();
uword payload_size = insns.Size();
payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment());
uword end = entry + payload_size;