Bug 1618198 part 23 - Implement InitProp* and InitElem* ops. r=iain

This adds buildInitPropOp instead of reusing buildSetPropOp because there are
some subtle differences between Init and Set. Longer term we should consider
splitting the MIR and CacheIR code as well so it becomes easier to reason about.

Differential Revision: https://phabricator.services.mozilla.com/D67804

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2020-03-24 07:04:44 +00:00
parent 5ce327d92a
commit 59e54831fd
3 changed files with 90 additions and 0 deletions

View File

@ -2160,3 +2160,75 @@ bool WarpBuilder::build_GetElemSuper(BytecodeLocation loc) {
return buildGetPropSuperOp(loc, obj, receiver, id);
}
bool WarpBuilder::buildInitPropOp(BytecodeLocation loc, MDefinition* obj,
MDefinition* id, MDefinition* val) {
// We need a GC post barrier. We don't need a TI barrier. We pass true for
// guardHoles, although the prototype chain is ignored for InitProp/InitElem.
bool strict = false;
bool needsPostBarrier = true;
bool needsTypeBarrier = false;
bool guardHoles = true;
auto* ins =
MSetPropertyCache::New(alloc(), obj, id, val, strict, needsPostBarrier,
needsTypeBarrier, guardHoles);
current->add(ins);
return resumeAfter(ins, loc);
}
bool WarpBuilder::build_InitProp(BytecodeLocation loc) {
MDefinition* val = current->pop();
MDefinition* obj = current->peek(-1);
PropertyName* name = loc.getPropertyName(script_);
MConstant* id = constant(StringValue(name));
return buildInitPropOp(loc, obj, id, val);
}
bool WarpBuilder::build_InitLockedProp(BytecodeLocation loc) {
return build_InitProp(loc);
}
bool WarpBuilder::build_InitHiddenProp(BytecodeLocation loc) {
return build_InitProp(loc);
}
bool WarpBuilder::build_InitElem(BytecodeLocation loc) {
MDefinition* val = current->pop();
MDefinition* id = current->pop();
MDefinition* obj = current->peek(-1);
return buildInitPropOp(loc, obj, id, val);
}
bool WarpBuilder::build_InitHiddenElem(BytecodeLocation loc) {
return build_InitElem(loc);
}
bool WarpBuilder::build_InitElemArray(BytecodeLocation loc) {
MDefinition* val = current->pop();
MDefinition* obj = current->peek(-1);
// Note: getInitElemArrayIndex asserts the index fits in int32_t.
uint32_t index = loc.getInitElemArrayIndex();
MConstant* indexConst = constant(Int32Value(index));
// TODO: we can probably just use MStoreElement like IonBuilder's fast path.
// Simpler than IonBuilder because we don't have to worry about maintaining TI
// invariants.
return buildInitPropOp(loc, obj, indexConst, val);
}
bool WarpBuilder::build_InitElemInc(BytecodeLocation loc) {
MDefinition* val = current->pop();
MDefinition* index = current->pop();
MDefinition* obj = current->peek(-1);
// Push index + 1.
MConstant* constOne = constant(Int32Value(1));
MAdd* nextIndex = MAdd::New(alloc(), index, constOne, MIRType::Int32);
current->add(nextIndex);
current->push(nextIndex);
return buildInitPropOp(loc, obj, index, val);
}

View File

@ -192,6 +192,13 @@ namespace jit {
_(GetImport) \
_(GetPropSuper) \
_(GetElemSuper) \
_(InitProp) \
_(InitLockedProp) \
_(InitHiddenProp) \
_(InitElem) \
_(InitHiddenElem) \
_(InitElemArray) \
_(InitElemInc) \
_(SetRval) \
_(Return) \
_(RetRval)
@ -288,6 +295,8 @@ class MOZ_STACK_CLASS WarpBuilder {
MDefinition* id);
MOZ_MUST_USE bool buildSetPropOp(BytecodeLocation loc, MDefinition* obj,
MDefinition* id, MDefinition* val);
MOZ_MUST_USE bool buildInitPropOp(BytecodeLocation loc, MDefinition* obj,
MDefinition* id, MDefinition* val);
MOZ_MUST_USE bool buildGetPropSuperOp(BytecodeLocation loc, MDefinition* obj,
MDefinition* receiver, MDefinition* id);

View File

@ -249,6 +249,15 @@ class BytecodeLocation {
return GET_ARGC(rawBytecode_);
}
uint32_t getInitElemArrayIndex() const {
MOZ_ASSERT(is(JSOp::InitElemArray));
uint32_t index = GET_UINT32(rawBytecode_);
MOZ_ASSERT(index <= INT32_MAX,
"the bytecode emitter must never generate JSOp::InitElemArray "
"with an index exceeding int32_t range");
return index;
}
FunctionPrefixKind getFunctionPrefixKind() const {
MOZ_ASSERT(is(JSOp::SetFunName));
return FunctionPrefixKind(GET_UINT8(rawBytecode_));