Line data Source code
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_StackSlotAllocator_h
8 : #define jit_StackSlotAllocator_h
9 :
10 : #include "mozilla/Unused.h"
11 :
12 : #include "jit/Registers.h"
13 :
14 : namespace js {
15 : namespace jit {
16 :
17 8 : class StackSlotAllocator
18 : {
19 : js::Vector<uint32_t, 4, SystemAllocPolicy> normalSlots;
20 : js::Vector<uint32_t, 4, SystemAllocPolicy> doubleSlots;
21 : uint32_t height_;
22 :
23 5 : void addAvailableSlot(uint32_t index) {
24 : // Ignoring OOM here (and below) is fine; it just means the stack slot
25 : // will be unused.
26 5 : mozilla::Unused << normalSlots.append(index);
27 5 : }
28 0 : void addAvailableDoubleSlot(uint32_t index) {
29 0 : mozilla::Unused << doubleSlots.append(index);
30 0 : }
31 :
32 0 : uint32_t allocateQuadSlot() {
33 : MOZ_ASSERT(SupportsSimd);
34 : // This relies on the fact that any architecture specific
35 : // alignment of the stack pointer is done a priori.
36 0 : if (height_ % 8 != 0)
37 0 : addAvailableSlot(height_ += 4);
38 0 : if (height_ % 16 != 0)
39 0 : addAvailableDoubleSlot(height_ += 8);
40 0 : return height_ += 16;
41 : }
42 61 : uint32_t allocateDoubleSlot() {
43 61 : if (!doubleSlots.empty())
44 0 : return doubleSlots.popCopy();
45 61 : if (height_ % 8 != 0)
46 5 : addAvailableSlot(height_ += 4);
47 61 : return height_ += 8;
48 : }
49 23 : uint32_t allocateSlot() {
50 23 : if (!normalSlots.empty())
51 4 : return normalSlots.popCopy();
52 19 : if (!doubleSlots.empty()) {
53 0 : uint32_t index = doubleSlots.popCopy();
54 0 : addAvailableSlot(index - 4);
55 0 : return index;
56 : }
57 19 : return height_ += 4;
58 : }
59 :
60 : public:
61 8 : StackSlotAllocator() : height_(0)
62 8 : { }
63 :
64 189 : static uint32_t width(LDefinition::Type type) {
65 189 : switch (type) {
66 : #if JS_BITS_PER_WORD == 32
67 : case LDefinition::GENERAL:
68 : case LDefinition::OBJECT:
69 : case LDefinition::SLOTS:
70 : #endif
71 : case LDefinition::INT32:
72 47 : case LDefinition::FLOAT32: return 4;
73 : #if JS_BITS_PER_WORD == 64
74 : case LDefinition::GENERAL:
75 : case LDefinition::OBJECT:
76 : case LDefinition::SLOTS:
77 : #endif
78 : #ifdef JS_PUNBOX64
79 : case LDefinition::BOX:
80 : #endif
81 : #ifdef JS_NUNBOX32
82 : case LDefinition::TYPE:
83 : case LDefinition::PAYLOAD:
84 : #endif
85 142 : case LDefinition::DOUBLE: return 8;
86 : case LDefinition::SINCOS:
87 : case LDefinition::SIMD128INT:
88 0 : case LDefinition::SIMD128FLOAT: return 16;
89 : }
90 0 : MOZ_CRASH("Unknown slot type");
91 : }
92 :
93 84 : uint32_t allocateSlot(LDefinition::Type type) {
94 84 : switch (width(type)) {
95 23 : case 4: return allocateSlot();
96 61 : case 8: return allocateDoubleSlot();
97 0 : case 16: return allocateQuadSlot();
98 : }
99 0 : MOZ_CRASH("Unknown slot width");
100 : }
101 :
102 8 : uint32_t stackHeight() const {
103 8 : return height_;
104 : }
105 : };
106 :
107 : } // namespace jit
108 : } // namespace js
109 :
110 : #endif /* jit_StackSlotAllocator_h */
|