1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_Safepoints_h 8 #define jit_Safepoints_h 9 10 #include "jit/BitSet.h" 11 #include "jit/CompactBuffer.h" 12 #include "jit/shared/Assembler-shared.h" 13 14 namespace js { 15 namespace jit { 16 17 struct SafepointSlotEntry; 18 19 class LAllocation; 20 class LSafepoint; 21 22 static const uint32_t INVALID_SAFEPOINT_OFFSET = uint32_t(-1); 23 24 class SafepointWriter { 25 CompactBufferWriter stream_; 26 BitSet frameSlots_; 27 BitSet argumentSlots_; 28 29 public: 30 explicit SafepointWriter(uint32_t slotCount, uint32_t argumentCount); 31 MOZ_MUST_USE bool init(TempAllocator& alloc); 32 33 private: 34 // A safepoint entry is written in the order these functions appear. 35 uint32_t startEntry(); 36 37 void writeOsiCallPointOffset(uint32_t osiPointOffset); 38 void writeGcRegs(LSafepoint* safepoint); 39 void writeGcSlots(LSafepoint* safepoint); 40 void writeValueSlots(LSafepoint* safepoint); 41 42 void writeSlotsOrElementsSlots(LSafepoint* safepoint); 43 44 #ifdef JS_NUNBOX32 45 void writeNunboxParts(LSafepoint* safepoint); 46 #endif 47 48 void endEntry(); 49 50 public: 51 void encode(LSafepoint* safepoint); 52 size()53 size_t size() const { return stream_.length(); } buffer()54 const uint8_t* buffer() const { return stream_.buffer(); } oom()55 bool oom() const { return stream_.oom(); } 56 }; 57 58 class SafepointReader { 59 CompactBufferReader stream_; 60 uint32_t frameSlots_; 61 uint32_t argumentSlots_; 62 uint32_t currentSlotChunk_; 63 bool currentSlotsAreStack_; 64 uint32_t nextSlotChunkNumber_; 65 uint32_t osiCallPointOffset_; 66 GeneralRegisterSet gcSpills_; 67 GeneralRegisterSet valueSpills_; 68 GeneralRegisterSet slotsOrElementsSpills_; 69 GeneralRegisterSet allGprSpills_; 70 FloatRegisterSet allFloatSpills_; 71 uint32_t nunboxSlotsRemaining_; 72 uint32_t slotsOrElementsSlotsRemaining_; 73 74 private: 75 void advanceFromGcRegs(); 76 void advanceFromGcSlots(); 77 void advanceFromValueSlots(); 78 void advanceFromNunboxSlots(); 79 MOZ_MUST_USE bool getSlotFromBitmap(SafepointSlotEntry* entry); 80 81 public: 82 SafepointReader(IonScript* script, const SafepointIndex* si); 83 84 static CodeLocationLabel InvalidationPatchPoint(IonScript* script, 85 const SafepointIndex* si); 86 osiCallPointOffset()87 uint32_t osiCallPointOffset() const { return osiCallPointOffset_; } gcSpills()88 LiveGeneralRegisterSet gcSpills() const { 89 return LiveGeneralRegisterSet(gcSpills_); 90 } slotsOrElementsSpills()91 LiveGeneralRegisterSet slotsOrElementsSpills() const { 92 return LiveGeneralRegisterSet(slotsOrElementsSpills_); 93 } valueSpills()94 LiveGeneralRegisterSet valueSpills() const { 95 return LiveGeneralRegisterSet(valueSpills_); 96 } allGprSpills()97 LiveGeneralRegisterSet allGprSpills() const { 98 return LiveGeneralRegisterSet(allGprSpills_); 99 } allFloatSpills()100 LiveFloatRegisterSet allFloatSpills() const { 101 return LiveFloatRegisterSet(allFloatSpills_); 102 } 103 uint32_t osiReturnPointOffset() const; 104 105 // Returns true if a slot was read, false if there are no more slots. 106 MOZ_MUST_USE bool getGcSlot(SafepointSlotEntry* entry); 107 108 // Returns true if a slot was read, false if there are no more value slots. 109 MOZ_MUST_USE bool getValueSlot(SafepointSlotEntry* entry); 110 111 // Returns true if a nunbox slot was read, false if there are no more 112 // nunbox slots. 113 MOZ_MUST_USE bool getNunboxSlot(LAllocation* type, LAllocation* payload); 114 115 // Returns true if a slot was read, false if there are no more slots. 116 MOZ_MUST_USE bool getSlotsOrElementsSlot(SafepointSlotEntry* entry); 117 }; 118 119 } // namespace jit 120 } // namespace js 121 122 #endif /* jit_Safepoints_h */ 123