1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * vim: set ts=8 sts=4 et sw=4 tw=99: 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 { 26 CompactBufferWriter stream_; 27 BitSet frameSlots_; 28 BitSet argumentSlots_; 29 30 public: 31 explicit SafepointWriter(uint32_t slotCount, uint32_t argumentCount); 32 bool init(TempAllocator& alloc); 33 34 private: 35 // A safepoint entry is written in the order these functions appear. 36 uint32_t startEntry(); 37 38 void writeOsiCallPointOffset(uint32_t osiPointOffset); 39 void writeGcRegs(LSafepoint* safepoint); 40 void writeGcSlots(LSafepoint* safepoint); 41 void writeValueSlots(LSafepoint* safepoint); 42 43 void writeSlotsOrElementsSlots(LSafepoint* safepoint); 44 45 #ifdef JS_NUNBOX32 46 void writeNunboxParts(LSafepoint* safepoint); 47 #endif 48 49 void endEntry(); 50 51 public: 52 void encode(LSafepoint* safepoint); 53 size()54 size_t size() const { 55 return stream_.length(); 56 } buffer()57 const uint8_t* buffer() const { 58 return stream_.buffer(); 59 } oom()60 bool oom() const { 61 return stream_.oom(); 62 } 63 }; 64 65 class SafepointReader 66 { 67 CompactBufferReader stream_; 68 uint32_t frameSlots_; 69 uint32_t argumentSlots_; 70 uint32_t currentSlotChunk_; 71 bool currentSlotsAreStack_; 72 uint32_t nextSlotChunkNumber_; 73 uint32_t osiCallPointOffset_; 74 GeneralRegisterSet gcSpills_; 75 GeneralRegisterSet valueSpills_; 76 GeneralRegisterSet slotsOrElementsSpills_; 77 GeneralRegisterSet allGprSpills_; 78 FloatRegisterSet allFloatSpills_; 79 uint32_t nunboxSlotsRemaining_; 80 uint32_t slotsOrElementsSlotsRemaining_; 81 82 private: 83 void advanceFromGcRegs(); 84 void advanceFromGcSlots(); 85 void advanceFromValueSlots(); 86 void advanceFromNunboxSlots(); 87 bool getSlotFromBitmap(SafepointSlotEntry* entry); 88 89 public: 90 SafepointReader(IonScript* script, const SafepointIndex* si); 91 92 static CodeLocationLabel InvalidationPatchPoint(IonScript* script, const SafepointIndex* si); 93 osiCallPointOffset()94 uint32_t osiCallPointOffset() const { 95 return osiCallPointOffset_; 96 } gcSpills()97 LiveGeneralRegisterSet gcSpills() const { 98 return LiveGeneralRegisterSet(gcSpills_); 99 } slotsOrElementsSpills()100 LiveGeneralRegisterSet slotsOrElementsSpills() const { 101 return LiveGeneralRegisterSet(slotsOrElementsSpills_); 102 } valueSpills()103 LiveGeneralRegisterSet valueSpills() const { 104 return LiveGeneralRegisterSet(valueSpills_); 105 } allGprSpills()106 LiveGeneralRegisterSet allGprSpills() const { 107 return LiveGeneralRegisterSet(allGprSpills_); 108 } allFloatSpills()109 LiveFloatRegisterSet allFloatSpills() const { 110 return LiveFloatRegisterSet(allFloatSpills_); 111 } 112 uint32_t osiReturnPointOffset() const; 113 114 // Returns true if a slot was read, false if there are no more slots. 115 bool getGcSlot(SafepointSlotEntry* entry); 116 117 // Returns true if a slot was read, false if there are no more value slots. 118 bool getValueSlot(SafepointSlotEntry* entry); 119 120 // Returns true if a nunbox slot was read, false if there are no more 121 // nunbox slots. 122 bool getNunboxSlot(LAllocation* type, LAllocation* payload); 123 124 // Returns true if a slot was read, false if there are no more slots. 125 bool getSlotsOrElementsSlot(SafepointSlotEntry* entry); 126 }; 127 128 } // namespace jit 129 } // namespace js 130 131 #endif /* jit_Safepoints_h */ 132