From 3bf67964400ed7a769284d233552f64278092866 Mon Sep 17 00:00:00 2001 From: Regis Crelier Date: Fri, 11 Nov 2016 11:09:37 -0800 Subject: [PATCH] Clean up encoding of size and single entry flag in Instructions. R=vegorov@google.com Review URL: https://codereview.chromium.org/2490363002 . --- runtime/vm/object.cc | 13 +++++----- runtime/vm/object.h | 52 ++++++++++++++++++++++++++++++---------- runtime/vm/precompiler.h | 2 +- runtime/vm/raw_object.cc | 7 +++--- runtime/vm/raw_object.h | 4 +++- runtime/vm/snapshot.cc | 4 ++-- 6 files changed, 55 insertions(+), 27 deletions(-) diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 62a4bf2ea62..87d48c82133 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -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(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 { diff --git a/runtime/vm/object.h b/runtime/vm/object.h index e06c9b05e2e..dbf901e958e 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -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 {}; + class FlagsBits : public BitField {}; + // 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(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(instr.size()); + return offset < static_cast(instr.Size()); } // Returns true if there is a debugger breakpoint set in this code object. diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h index 15e39348f5b..2566a7883ea 100644 --- a/runtime/vm/precompiler.h +++ b/runtime/vm/precompiler.h @@ -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); diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index b731a90f950..bfe850aacb0 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc @@ -68,7 +68,7 @@ intptr_t RawObject::SizeFromClass() const { case kInstructionsCid: { const RawInstructions* raw_instructions = reinterpret_cast(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(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); } diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index ab37588eeb5..71b64583372 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -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); } diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc index 5769ba0ad76..427a19600ca 100644 --- a/runtime/vm/snapshot.cc +++ b/runtime/vm/snapshot.cc @@ -814,7 +814,7 @@ void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer, NoSafepointScope no_safepoint; uword beginning = reinterpret_cast(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(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;