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/. */
7 #ifndef jit_StackSlotAllocator_h
8 #define jit_StackSlotAllocator_h
10 #include "jit/Registers.h"
15 class StackSlotAllocator
{
16 js::Vector
<uint32_t, 4, SystemAllocPolicy
> normalSlots
;
17 js::Vector
<uint32_t, 4, SystemAllocPolicy
> doubleSlots
;
20 void addAvailableSlot(uint32_t index
) {
21 // Ignoring OOM here (and below) is fine; it just means the stack slot
23 (void)normalSlots
.append(index
);
25 void addAvailableDoubleSlot(uint32_t index
) {
26 (void)doubleSlots
.append(index
);
29 uint32_t allocateQuadSlot() {
30 // This relies on the fact that any architecture specific
31 // alignment of the stack pointer is done a priori.
32 if (height_
% 8 != 0) {
33 addAvailableSlot(height_
+= 4);
35 if (height_
% 16 != 0) {
36 addAvailableDoubleSlot(height_
+= 8);
40 uint32_t allocateDoubleSlot() {
41 if (!doubleSlots
.empty()) {
42 return doubleSlots
.popCopy();
44 if (height_
% 8 != 0) {
45 addAvailableSlot(height_
+= 4);
49 uint32_t allocateSlot() {
50 if (!normalSlots
.empty()) {
51 return normalSlots
.popCopy();
53 if (!doubleSlots
.empty()) {
54 uint32_t index
= doubleSlots
.popCopy();
55 addAvailableSlot(index
- 4);
62 StackSlotAllocator() : height_(0) {}
64 void allocateStackArea(LStackArea
* alloc
) {
65 uint32_t size
= alloc
->size();
67 MOZ_ASSERT(size
% 4 == 0);
68 switch (alloc
->alignment()) {
70 if ((height_
+ size
) % 8 != 0) {
71 addAvailableSlot(height_
+= 4);
75 MOZ_CRASH("unexpected stack results area alignment");
77 MOZ_ASSERT((height_
+ size
) % alloc
->alignment() == 0);
80 alloc
->setBase(height_
);
83 static uint32_t width(LDefinition::Type type
) {
85 #if JS_BITS_PER_WORD == 32
86 case LDefinition::GENERAL
:
87 case LDefinition::OBJECT
:
88 case LDefinition::SLOTS
:
89 case LDefinition::WASM_ANYREF
:
92 case LDefinition::TYPE
:
93 case LDefinition::PAYLOAD
:
95 case LDefinition::INT32
:
96 case LDefinition::FLOAT32
:
98 #if JS_BITS_PER_WORD == 64
99 case LDefinition::GENERAL
:
100 case LDefinition::OBJECT
:
101 case LDefinition::SLOTS
:
102 case LDefinition::WASM_ANYREF
:
105 case LDefinition::BOX
:
107 case LDefinition::DOUBLE
:
109 case LDefinition::SIMD128
:
111 case LDefinition::STACKRESULTS
:
112 MOZ_CRASH("Stack results area must be allocated manually");
114 MOZ_CRASH("Unknown slot type");
117 uint32_t allocateSlot(LDefinition::Type type
) {
118 switch (width(type
)) {
120 return allocateSlot();
122 return allocateDoubleSlot();
124 return allocateQuadSlot();
126 MOZ_CRASH("Unknown slot width");
129 uint32_t stackHeight() const { return height_
; }
135 #endif /* jit_StackSlotAllocator_h */