Commit 7a3366fb authored by clemensh's avatar clemensh Committed by Commit bot

[compiler] Allow for StackSlots of arbitrary size

This will be used to pass parameters of wasm functions to the wasm
interpreter. All of them need to be packed into one buffer, which is
then passed to the interpreter.

R=ahaas@chromium.org, titzer@chromium.org
BUG=v8:5822

Review-Url: https://codereview.chromium.org/2624183002
Cr-Commit-Position: refs/heads/master@{#42239}
parent e9048949
......@@ -113,9 +113,9 @@ class Frame : public ZoneObject {
int AllocateSpillSlot(int width) {
int frame_slot_count_before = frame_slot_count_;
int slot = AllocateAlignedFrameSlot(width);
spill_slot_count_ += (frame_slot_count_ - frame_slot_count_before);
return slot;
AllocateAlignedFrameSlots(width);
spill_slot_count_ += frame_slot_count_ - frame_slot_count_before;
return frame_slot_count_ - 1;
}
int AlignFrame(int alignment = kDoubleSize);
......@@ -131,23 +131,15 @@ class Frame : public ZoneObject {
static const int kJSFunctionSlot = 3 + StandardFrameConstants::kCPSlotCount;
private:
int AllocateAlignedFrameSlot(int width) {
DCHECK(width == 4 || width == 8 || width == 16);
if (kPointerSize == 4) {
// Skip one slot if necessary.
if (width > kPointerSize) {
frame_slot_count_++;
frame_slot_count_ |= 1;
// 2 extra slots if width == 16.
frame_slot_count_ += (width & 16) / 8;
}
} else {
// No alignment when slots are 8 bytes.
DCHECK_EQ(8, kPointerSize);
// 1 extra slot if width == 16.
frame_slot_count_ += (width & 16) / 16;
}
return frame_slot_count_++;
void AllocateAlignedFrameSlots(int width) {
DCHECK_LT(0, width);
int new_frame_slots = (width + kPointerSize - 1) / kPointerSize;
// Align to 8 bytes if width is a multiple of 8 bytes, and to 16 bytes if
// multiple of 16.
int align_to = (width & 15) == 0 ? 16 : (width & 7) == 0 ? 8 : kPointerSize;
frame_slot_count_ =
RoundUp(frame_slot_count_ + new_frame_slots, align_to / kPointerSize);
DCHECK_LT(0, frame_slot_count_);
}
private:
......
......@@ -1632,7 +1632,7 @@ void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
}
void InstructionSelector::VisitStackSlot(Node* node) {
int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op()));
int size = StackSlotSizeOf(node->op());
int slot = frame_->AllocateSpillSlot(size);
OperandGenerator g(this);
......
......@@ -70,9 +70,9 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
return OpParameter<CheckedStoreRepresentation>(op);
}
MachineRepresentation StackSlotRepresentationOf(Operator const* op) {
int StackSlotSizeOf(Operator const* op) {
DCHECK_EQ(IrOpcode::kStackSlot, op->opcode());
return OpParameter<MachineRepresentation>(op);
return OpParameter<int>(op);
}
MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
......@@ -458,6 +458,15 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(kWord16) \
V(kWord32)
#define STACK_SLOT_CACHED_SIZES_LIST(V) V(4) V(8) V(16)
struct StackSlotOperator : public Operator1<int> {
explicit StackSlotOperator(int size)
: Operator1<int>(IrOpcode::kStackSlot,
Operator::kNoDeopt | Operator::kNoThrow, "StackSlot", 0,
0, 0, 1, 0, 0, size) {}
};
struct MachineOperatorGlobalCache {
#define PURE(Name, properties, value_input_count, control_input_count, \
output_count) \
......@@ -522,17 +531,12 @@ struct MachineOperatorGlobalCache {
MACHINE_TYPE_LIST(LOAD)
#undef LOAD
#define STACKSLOT(Type) \
struct StackSlot##Type##Operator final \
: public Operator1<MachineRepresentation> { \
StackSlot##Type##Operator() \
: Operator1<MachineRepresentation>( \
IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow, \
"StackSlot", 0, 0, 0, 1, 0, 0, \
MachineType::Type().representation()) {} \
}; \
StackSlot##Type##Operator kStackSlot##Type;
MACHINE_TYPE_LIST(STACKSLOT)
#define STACKSLOT(Size) \
struct StackSlotOfSize##Size##Operator final : public StackSlotOperator { \
StackSlotOfSize##Size##Operator() : StackSlotOperator(Size) {} \
}; \
StackSlotOfSize##Size##Operator kStackSlotSize##Size;
STACK_SLOT_CACHED_SIZES_LIST(STACKSLOT)
#undef STACKSLOT
#define STORE(Type) \
......@@ -735,15 +739,21 @@ const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) {
return nullptr;
}
const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep) {
#define STACKSLOT(Type) \
if (rep == MachineType::Type().representation()) { \
return &cache_.kStackSlot##Type; \
const Operator* MachineOperatorBuilder::StackSlot(int size) {
DCHECK_LE(0, size);
#define CASE_CACHED_SIZE(Size) \
case Size: \
return &cache_.kStackSlotSize##Size;
switch (size) {
STACK_SLOT_CACHED_SIZES_LIST(CASE_CACHED_SIZE);
default:
return new (zone_) StackSlotOperator(size);
}
MACHINE_TYPE_LIST(STACKSLOT)
#undef STACKSLOT
UNREACHABLE();
return nullptr;
#undef CASE_CACHED_SIZE
}
const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep) {
return StackSlot(1 << ElementSizeLog2Of(rep));
}
const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
......
......@@ -93,7 +93,7 @@ typedef MachineRepresentation CheckedStoreRepresentation;
CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
MachineRepresentation StackSlotRepresentationOf(Operator const* op);
int StackSlotSizeOf(Operator const* op);
MachineRepresentation AtomicStoreRepresentationOf(Operator const* op);
......@@ -619,6 +619,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
// unaligned store [base + index], value
const Operator* UnalignedStore(UnalignedStoreRepresentation rep);
const Operator* StackSlot(int size);
const Operator* StackSlot(MachineRepresentation rep);
// Access to the machine stack.
......
......@@ -570,8 +570,7 @@ TEST_F(Int64LoweringTest, F64ReinterpretI64) {
MachineRepresentation::kFloat64);
Capture<Node*> stack_slot_capture;
Matcher<Node*> stack_slot_matcher =
IsStackSlot(MachineRepresentation::kWord64);
Matcher<Node*> stack_slot_matcher = IsStackSlot(sizeof(int64_t));
Capture<Node*> store_capture;
Matcher<Node*> store_matcher =
......@@ -602,8 +601,7 @@ TEST_F(Int64LoweringTest, I64ReinterpretF64) {
MachineRepresentation::kWord64);
Capture<Node*> stack_slot;
Matcher<Node*> stack_slot_matcher =
IsStackSlot(MachineRepresentation::kWord64);
Matcher<Node*> stack_slot_matcher = IsStackSlot(sizeof(int64_t));
Capture<Node*> store;
Matcher<Node*> store_matcher = IsStore(
......
......@@ -1339,24 +1339,24 @@ STORE_MATCHER(UnalignedStore)
class IsStackSlotMatcher final : public NodeMatcher {
public:
explicit IsStackSlotMatcher(const Matcher<MachineRepresentation>& rep_matcher)
: NodeMatcher(IrOpcode::kStackSlot), rep_matcher_(rep_matcher) {}
explicit IsStackSlotMatcher(const Matcher<int>& size_matcher)
: NodeMatcher(IrOpcode::kStackSlot), size_matcher_(size_matcher) {}
void DescribeTo(std::ostream* os) const final {
NodeMatcher::DescribeTo(os);
*os << " whose rep (";
rep_matcher_.DescribeTo(os);
*os << " whose size (";
size_matcher_.DescribeTo(os);
*os << ")";
}
bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
return (NodeMatcher::MatchAndExplain(node, listener) &&
PrintMatchAndExplain(OpParameter<MachineRepresentation>(node),
"rep", rep_matcher_, listener));
PrintMatchAndExplain(OpParameter<int>(node), "size", size_matcher_,
listener));
}
private:
const Matcher<MachineRepresentation> rep_matcher_;
const Matcher<int> size_matcher_;
};
class IsToNumberMatcher final : public NodeMatcher {
......@@ -2175,8 +2175,8 @@ Matcher<Node*> IsUnalignedStore(
control_matcher));
}
Matcher<Node*> IsStackSlot(const Matcher<MachineRepresentation>& rep_matcher) {
return MakeMatcher(new IsStackSlotMatcher(rep_matcher));
Matcher<Node*> IsStackSlot(const Matcher<int>& size_matcher) {
return MakeMatcher(new IsStackSlotMatcher(size_matcher));
}
Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
......
......@@ -333,7 +333,7 @@ Matcher<Node*> IsUnalignedStore(
const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
const Matcher<Node*>& value_matcher, const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsStackSlot(const Matcher<MachineRepresentation>& rep_matcher);
Matcher<Node*> IsStackSlot(const Matcher<int>& size_matcher);
Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord32Or(const Matcher<Node*>& lhs_matcher,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment