Backed out changeset aca2e6cff6b9 (bug 1578418) for bustages complaining about WasmBaselineCompile.cpp CLOSED TREE

This commit is contained in:
Bogdan Tara 2019-10-22 17:19:01 +03:00
Родитель f16e836b61
Коммит 8fb59cb8ed
6 изменённых файлов: 449 добавлений и 1124 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1764,13 +1764,11 @@ static bool EmitF64Const(FunctionCompiler& f) {
}
static bool EmitBlock(FunctionCompiler& f) {
ResultType params;
return f.iter().readBlock(&params) && f.startBlock();
return f.iter().readBlock() && f.startBlock();
}
static bool EmitLoop(FunctionCompiler& f) {
ResultType params;
if (!f.iter().readLoop(&params)) {
if (!f.iter().readLoop()) {
return false;
}
@ -1786,9 +1784,8 @@ static bool EmitLoop(FunctionCompiler& f) {
}
static bool EmitIf(FunctionCompiler& f) {
ResultType params;
MDefinition* condition = nullptr;
if (!f.iter().readIf(&params, &condition)) {
if (!f.iter().readIf(&condition)) {
return false;
}
@ -1802,10 +1799,9 @@ static bool EmitIf(FunctionCompiler& f) {
}
static bool EmitElse(FunctionCompiler& f) {
ResultType paramType;
ResultType resultType;
ResultType thenType;
DefVector thenValues;
if (!f.iter().readElse(&paramType, &resultType, &thenValues)) {
if (!f.iter().readElse(&thenType, &thenValues)) {
return false;
}

Просмотреть файл

@ -720,11 +720,10 @@ class MOZ_STACK_CLASS OpIter : private Policy {
MOZ_MUST_USE bool readFunctionStart(uint32_t funcIndex);
MOZ_MUST_USE bool readFunctionEnd(const uint8_t* bodyEnd);
MOZ_MUST_USE bool readReturn(ValueVector* values);
MOZ_MUST_USE bool readBlock(ResultType* paramType);
MOZ_MUST_USE bool readLoop(ResultType* paramType);
MOZ_MUST_USE bool readIf(ResultType* paramType, Value* condition);
MOZ_MUST_USE bool readElse(ResultType* paramType, ResultType* resultType,
ValueVector* thenValues);
MOZ_MUST_USE bool readBlock();
MOZ_MUST_USE bool readLoop();
MOZ_MUST_USE bool readIf(Value* condition);
MOZ_MUST_USE bool readElse(ResultType* thenType, ValueVector* thenValues);
MOZ_MUST_USE bool readEnd(LabelKind* kind, ResultType* type,
ValueVector* values);
void popEnd();
@ -1263,7 +1262,7 @@ inline bool OpIter<Policy>::readReturn(ValueVector* values) {
}
template <typename Policy>
inline bool OpIter<Policy>::readBlock(ResultType* paramType) {
inline bool OpIter<Policy>::readBlock() {
MOZ_ASSERT(Classify(op_) == OpKind::Block);
BlockType type;
@ -1271,12 +1270,11 @@ inline bool OpIter<Policy>::readBlock(ResultType* paramType) {
return false;
}
*paramType = type.params();
return pushControl(LabelKind::Block, type);
}
template <typename Policy>
inline bool OpIter<Policy>::readLoop(ResultType* paramType) {
inline bool OpIter<Policy>::readLoop() {
MOZ_ASSERT(Classify(op_) == OpKind::Loop);
BlockType type;
@ -1284,12 +1282,11 @@ inline bool OpIter<Policy>::readLoop(ResultType* paramType) {
return false;
}
*paramType = type.params();
return pushControl(LabelKind::Loop, type);
}
template <typename Policy>
inline bool OpIter<Policy>::readIf(ResultType* paramType, Value* condition) {
inline bool OpIter<Policy>::readIf(Value* condition) {
MOZ_ASSERT(Classify(op_) == OpKind::If);
BlockType type;
@ -1305,14 +1302,12 @@ inline bool OpIter<Policy>::readIf(ResultType* paramType, Value* condition) {
return false;
}
*paramType = type.params();
size_t paramsLength = type.params().length();
return thenParamStack_.append(valueStack_.end() - paramsLength, paramsLength);
}
template <typename Policy>
inline bool OpIter<Policy>::readElse(ResultType* paramType,
ResultType* resultType,
inline bool OpIter<Policy>::readElse(ResultType* thenType,
ValueVector* values) {
MOZ_ASSERT(Classify(op_) == OpKind::Else);
@ -1321,8 +1316,7 @@ inline bool OpIter<Policy>::readElse(ResultType* paramType,
return fail("else can only be used within an if");
}
*paramType = block.type().params();
if (!checkStackAtEndOfBlock(resultType, values)) {
if (!checkStackAtEndOfBlock(thenType, values)) {
return false;
}
@ -1353,8 +1347,7 @@ inline bool OpIter<Policy>::readEnd(LabelKind* kind, ResultType* type,
// If an `if` block ends with `end` instead of `else`, then we must
// additionally validate that the then-block doesn't push anything.
if (block.kind() == LabelKind::Then &&
block.type().params() != block.type().results()) {
if (block.kind() == LabelKind::Then && !block.resultType().empty()) {
return fail("if without else with a result value");
}

Просмотреть файл

@ -39,93 +39,6 @@ typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
/*****************************************************************************/
// ABIResultIter implementation
static uint32_t ResultStackSize(ValType type) {
switch (type.code()) {
case ValType::I32:
return ABIResult::StackSizeOfInt32;
case ValType::I64:
return ABIResult::StackSizeOfInt64;
case ValType::F32:
return ABIResult::StackSizeOfFloat;
case ValType::F64:
return ABIResult::StackSizeOfDouble;
case ValType::Ref:
case ValType::FuncRef:
case ValType::AnyRef:
return ABIResult::StackSizeOfPtr;
case ValType::NullRef:
default:
MOZ_CRASH("Unexpected result type");
}
}
uint32_t ABIResult::size() const { return ResultStackSize(type()); }
void ABIResultIter::settleRegister(ValType type) {
MOZ_ASSERT(!done());
MOZ_ASSERT(index() < RegisterResultCount);
static_assert(RegisterResultCount == 1, "expected a single register result");
switch (type.code()) {
case ValType::I32:
cur_ = ABIResult(type, ReturnReg);
break;
case ValType::I64:
cur_ = ABIResult(type, ReturnReg64);
break;
case ValType::F32:
cur_ = ABIResult(type, ReturnFloat32Reg);
break;
case ValType::F64:
cur_ = ABIResult(type, ReturnDoubleReg);
break;
case ValType::Ref:
case ValType::FuncRef:
case ValType::AnyRef:
cur_ = ABIResult(type, ReturnReg);
break;
case ValType::NullRef:
default:
MOZ_CRASH("Unexpected result type");
}
}
void ABIResultIter::settleNext() {
MOZ_ASSERT(direction_ == Next);
MOZ_ASSERT(!done());
uint32_t typeIndex = count_ - index_ - 1;
ValType type = type_[typeIndex];
if (index_ < RegisterResultCount) {
settleRegister(type);
return;
}
cur_ = ABIResult(type, nextStackOffset_);
nextStackOffset_ += ResultStackSize(type);
}
void ABIResultIter::settlePrev() {
MOZ_ASSERT(direction_ == Prev);
MOZ_ASSERT(!done());
uint32_t typeIndex = index_;
ValType type = type_[typeIndex];
if (count_ - index_ - 1 < RegisterResultCount) {
settleRegister(type);
return;
}
uint32_t size = ResultStackSize(type);
MOZ_ASSERT(nextStackOffset_ >= size);
nextStackOffset_ -= size;
cur_ = ABIResult(type, nextStackOffset_);
}
#ifdef WASM_CODEGEN_DEBUG
template <class Closure>
static void GenPrint(DebugChannel channel, MacroAssembler& masm,

Просмотреть файл

@ -20,227 +20,10 @@
#define wasm_stubs_h
#include "wasm/WasmGenerator.h"
#include "wasm/WasmOpIter.h"
namespace js {
namespace wasm {
// ValType and location for a single result: either in a register or on the
// stack.
class ABIResult {
ValType type_;
enum class Location { Gpr, Gpr64, Fpr, Stack } loc_;
union {
Register gpr_;
Register64 gpr64_;
FloatRegister fpr_;
uint32_t stackOffset_;
};
void validate() {
#ifdef DEBUG
if (onStack()) {
return;
}
MOZ_ASSERT(inRegister());
switch (type_.code()) {
case ValType::I32:
MOZ_ASSERT(loc_ == Location::Gpr);
break;
case ValType::I64:
MOZ_ASSERT(loc_ == Location::Gpr64);
break;
case ValType::F32:
case ValType::F64:
MOZ_ASSERT(loc_ == Location::Fpr);
break;
case ValType::AnyRef:
case ValType::FuncRef:
case ValType::Ref:
MOZ_ASSERT(loc_ == Location::Gpr);
break;
default:
MOZ_CRASH("bad value type");
}
#endif
}
friend class ABIResultIter;
ABIResult(){};
public:
// Sizes of items in the stack area.
//
// The size values come from the implementations of Push() in
// MacroAssembler-x86-shared.cpp and MacroAssembler-arm-shared.cpp, and from
// VFPRegister::size() in Architecture-arm.h.
//
// On ARM unlike on x86 we push a single for float.
static constexpr size_t StackSizeOfPtr = sizeof(intptr_t);
static constexpr size_t StackSizeOfInt32 = StackSizeOfPtr;
static constexpr size_t StackSizeOfInt64 = sizeof(int64_t);
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32)
static constexpr size_t StackSizeOfFloat = sizeof(float);
#else
static constexpr size_t StackSizeOfFloat = sizeof(double);
#endif
static constexpr size_t StackSizeOfDouble = sizeof(double);
ABIResult(ValType type, Register gpr)
: type_(type), loc_(Location::Gpr), gpr_(gpr) {
validate();
}
ABIResult(ValType type, Register64 gpr64)
: type_(type), loc_(Location::Gpr64), gpr64_(gpr64) {
validate();
}
ABIResult(ValType type, FloatRegister fpr)
: type_(type), loc_(Location::Fpr), fpr_(fpr) {
validate();
}
ABIResult(ValType type, uint32_t stackOffset)
: type_(type), loc_(Location::Stack), stackOffset_(stackOffset) {
validate();
}
ValType type() const { return type_; }
bool onStack() const { return loc_ == Location::Stack; }
bool inRegister() const { return !onStack(); }
Register gpr() const {
MOZ_ASSERT(loc_ == Location::Gpr);
return gpr_;
}
Register64 gpr64() const {
MOZ_ASSERT(loc_ == Location::Gpr64);
return gpr64_;
}
FloatRegister fpr() const {
MOZ_ASSERT(loc_ == Location::Fpr);
return fpr_;
}
// Offset from SP.
uint32_t stackOffset() const {
MOZ_ASSERT(loc_ == Location::Stack);
return stackOffset_;
}
uint32_t size() const;
};
// Just as WebAssembly functions can take multiple arguments, they can also
// return multiple results. As with a call, a limited number of results will be
// located in registers, and the rest will be stored in a stack area. The
// |ABIResultIter| computes result locations, given a |ResultType|.
//
// Recall that a |ResultType| represents a sequence of value types t1..tN,
// indexed from 1 to N. In principle it doesn't matter how we decide which
// results get to be in registers and which go to the stack. To better
// harmonize with WebAssembly's abstract stack machine, whose properties are
// taken advantage of by the baseline compiler, our strategy is to start
// allocating result locations in "reverse" order: from result N down to 1.
//
// If a result with index I is in a register, then all results with index J > I
// are also in registers. If a result I is on the stack, then all results with
// index K < I are also on the stack, farther away from the stack pointer than
// result I.
//
// Currently only a single result is ever stored in a register, though this may
// change in the future on register-rich platforms.
//
// NB: The baseline compiler also uses thie ABI for locations of block
// parameters and return values, within individual WebAssembly functions.
class ABIResultIter {
ResultType type_;
uint32_t count_;
uint32_t index_;
uint32_t nextStackOffset_;
enum { Next, Prev } direction_;
ABIResult cur_;
void settleRegister(ValType type);
void settleNext();
void settlePrev();
static constexpr size_t RegisterResultCount = 1;
public:
explicit ABIResultIter(const ResultType& type)
: type_(type), count_(type.length()) {
reset();
}
void reset() {
index_ = nextStackOffset_ = 0;
direction_ = Next;
if (!done()) {
settleNext();
}
}
bool done() const { return index_ == count_; }
uint32_t index() const { return index_; }
uint32_t count() const { return count_; }
uint32_t remaining() const { return count_ - index_; }
void switchToNext() {
MOZ_ASSERT(direction_ == Prev);
if (!done() && cur().onStack()) {
nextStackOffset_ += cur().size();
}
index_ = count_ - index_;
direction_ = Next;
if (!done()) {
settleNext();
}
}
void switchToPrev() {
MOZ_ASSERT(direction_ == Next);
if (!done() && cur().onStack()) {
nextStackOffset_ -= cur().size();
}
index_ = count_ - index_;
direction_ = Prev;
if (!done()) settlePrev();
}
void next() {
MOZ_ASSERT(direction_ == Next);
MOZ_ASSERT(!done());
index_++;
if (!done()) {
settleNext();
}
}
void prev() {
MOZ_ASSERT(direction_ == Prev);
MOZ_ASSERT(!done());
index_++;
if (!done()) {
settlePrev();
}
}
const ABIResult& cur() const {
MOZ_ASSERT(!done());
return cur_;
}
uint32_t stackBytesConsumedSoFar() const { return nextStackOffset_; }
static inline bool HasStackResults(const ResultType& type) {
return type.length() > RegisterResultCount;
}
static uint32_t MeasureStackBytes(const ResultType& type) {
if (!HasStackResults(type)) {
return 0;
}
ABIResultIter iter(type);
while (!iter.done()) {
iter.next();
}
return iter.stackBytesConsumedSoFar();
}
};
extern bool GenerateBuiltinThunk(jit::MacroAssembler& masm,
jit::ABIFunctionType abiType,
ExitReason exitReason, void* funcPtr,

Просмотреть файл

@ -578,13 +578,13 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
&nothing));
}
case uint16_t(Op::Block):
CHECK(iter.readBlock(&unusedType));
CHECK(iter.readBlock());
case uint16_t(Op::Loop):
CHECK(iter.readLoop(&unusedType));
CHECK(iter.readLoop());
case uint16_t(Op::If):
CHECK(iter.readIf(&unusedType, &nothing));
CHECK(iter.readIf(&nothing));
case uint16_t(Op::Else):
CHECK(iter.readElse(&unusedType, &unusedType, &nothings));
CHECK(iter.readElse(&unusedType, &nothings));
case uint16_t(Op::I32Clz):
case uint16_t(Op::I32Ctz):
case uint16_t(Op::I32Popcnt):