mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1064358 - Recover CreateThisWithTemplate. r=jandem
This commit is contained in:
parent
f3e5d3181a
commit
c8abcdcbb9
@ -1,5 +1,5 @@
|
||||
setJitCompilerOption("baseline.warmup.trigger", 10);
|
||||
setJitCompilerOption("ion.warmup.trigger", 20);
|
||||
setJitCompilerOption("ion.warmup.trigger", 30);
|
||||
|
||||
var uceFault = function (i) {
|
||||
if (i > 98)
|
||||
@ -112,6 +112,20 @@ function dynamicSlots(i) {
|
||||
assertEq(obj.p0 + obj.p10 + obj.p20 + obj.p30 + obj.p40, 5 * i + 100);
|
||||
}
|
||||
|
||||
// Check that we can correctly recover allocations of new objects.
|
||||
function Point(x, y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
function createThisWithTemplate(i)
|
||||
{
|
||||
var p = new Point(i - 1, i + 1);
|
||||
bailout();
|
||||
assertEq(p.y - p.x, 2);
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < 100; i++) {
|
||||
notSoEmpty1(i);
|
||||
@ -121,4 +135,5 @@ for (var i = 0; i < 100; i++) {
|
||||
withinIf(i);
|
||||
unknownLoad(i);
|
||||
dynamicSlots(i);
|
||||
createThisWithTemplate(i);
|
||||
}
|
||||
|
@ -5171,9 +5171,11 @@ IonBuilder::createThisScriptedSingleton(JSFunction *target, MDefinition *callee)
|
||||
|
||||
// Generate an inline path to create a new |this| object with
|
||||
// the given singleton prototype.
|
||||
MConstant *templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject);
|
||||
MCreateThisWithTemplate *createThis =
|
||||
MCreateThisWithTemplate::New(alloc(), constraints(), templateObject,
|
||||
MCreateThisWithTemplate::New(alloc(), constraints(), templateConst,
|
||||
templateObject->type()->initialHeap(constraints()));
|
||||
current->add(templateConst);
|
||||
current->add(createThis);
|
||||
|
||||
return createThis;
|
||||
|
@ -3167,6 +3167,14 @@ MNewObject::shouldUseVM() const
|
||||
return obj->hasSingletonType() || obj->hasDynamicSlots();
|
||||
}
|
||||
|
||||
bool
|
||||
MCreateThisWithTemplate::canRecoverOnBailout() const
|
||||
{
|
||||
MOZ_ASSERT(!templateObject()->denseElementsAreCopyOnWrite());
|
||||
MOZ_ASSERT(!templateObject()->is<ArrayObject>());
|
||||
return true;
|
||||
}
|
||||
|
||||
MObjectState::MObjectState(MDefinition *obj)
|
||||
{
|
||||
// This instruction is only used as a summary for bailout paths.
|
||||
|
@ -3629,31 +3629,30 @@ class MAssertRange
|
||||
// Caller-side allocation of |this| for |new|:
|
||||
// Given a templateobject, construct |this| for JSOP_NEW
|
||||
class MCreateThisWithTemplate
|
||||
: public MNullaryInstruction
|
||||
: public MUnaryInstruction
|
||||
{
|
||||
// Template for |this|, provided by TI
|
||||
AlwaysTenuredObject templateObject_;
|
||||
gc::InitialHeap initialHeap_;
|
||||
|
||||
MCreateThisWithTemplate(types::CompilerConstraintList *constraints, JSObject *templateObject,
|
||||
MCreateThisWithTemplate(types::CompilerConstraintList *constraints, MConstant *templateConst,
|
||||
gc::InitialHeap initialHeap)
|
||||
: templateObject_(templateObject),
|
||||
: MUnaryInstruction(templateConst),
|
||||
initialHeap_(initialHeap)
|
||||
{
|
||||
setResultType(MIRType_Object);
|
||||
setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject));
|
||||
setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject()));
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(CreateThisWithTemplate);
|
||||
static MCreateThisWithTemplate *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
|
||||
JSObject *templateObject, gc::InitialHeap initialHeap)
|
||||
MConstant *templateConst, gc::InitialHeap initialHeap)
|
||||
{
|
||||
return new(alloc) MCreateThisWithTemplate(constraints, templateObject, initialHeap);
|
||||
return new(alloc) MCreateThisWithTemplate(constraints, templateConst, initialHeap);
|
||||
}
|
||||
|
||||
// Template for |this|, provided by TI.
|
||||
JSObject *templateObject() const {
|
||||
return templateObject_;
|
||||
return &getOperand(0)->toConstant()->value().toObject();
|
||||
}
|
||||
|
||||
gc::InitialHeap initialHeap() const {
|
||||
@ -3664,6 +3663,9 @@ class MCreateThisWithTemplate
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
||||
bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
bool canRecoverOnBailout() const;
|
||||
};
|
||||
|
||||
// Caller-side allocation of |this| for |new|:
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "builtin/RegExp.h"
|
||||
#include "builtin/TypedObject.h"
|
||||
|
||||
#include "gc/Heap.h"
|
||||
|
||||
#include "jit/JitFrameIterator.h"
|
||||
#include "jit/JitSpewer.h"
|
||||
#include "jit/MIR.h"
|
||||
@ -1094,6 +1096,42 @@ RNewDerivedTypedObject::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MCreateThisWithTemplate::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
MOZ_ASSERT(canRecoverOnBailout());
|
||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_CreateThisWithTemplate));
|
||||
writer.writeByte(bool(initialHeap() == gc::TenuredHeap));
|
||||
return true;
|
||||
}
|
||||
|
||||
RCreateThisWithTemplate::RCreateThisWithTemplate(CompactBufferReader &reader)
|
||||
{
|
||||
tenuredHeap_ = reader.readByte();
|
||||
}
|
||||
|
||||
bool
|
||||
RCreateThisWithTemplate::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
{
|
||||
RootedObject templateObject(cx, &iter.read().toObject());
|
||||
|
||||
// Use AutoEnterAnalysis to avoid invoking the object metadata callback
|
||||
// while bailing out, which could try to walk the stack.
|
||||
types::AutoEnterAnalysis enter(cx);
|
||||
|
||||
// See CodeGenerator::visitCreateThisWithTemplate
|
||||
gc::AllocKind allocKind = templateObject->asTenured()->getAllocKind();
|
||||
gc::InitialHeap initialHeap = tenuredHeap_ ? gc::TenuredHeap : gc::DefaultHeap;
|
||||
JSObject *resultObject = JSObject::copy(cx, allocKind, initialHeap, templateObject);
|
||||
if (!resultObject)
|
||||
return false;
|
||||
|
||||
RootedValue result(cx);
|
||||
result.setObject(*resultObject);
|
||||
iter.storeInstructionResult(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MObjectState::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
|
@ -54,6 +54,7 @@ namespace jit {
|
||||
_(NewObject) \
|
||||
_(NewArray) \
|
||||
_(NewDerivedTypedObject) \
|
||||
_(CreateThisWithTemplate) \
|
||||
_(ObjectState) \
|
||||
_(ArrayState)
|
||||
|
||||
@ -557,6 +558,21 @@ class RNewDerivedTypedObject MOZ_FINAL : public RInstruction
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RCreateThisWithTemplate MOZ_FINAL : public RInstruction
|
||||
{
|
||||
private:
|
||||
bool tenuredHeap_;
|
||||
|
||||
public:
|
||||
RINSTRUCTION_HEADER_(CreateThisWithTemplate)
|
||||
|
||||
virtual uint32_t numOperands() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RObjectState MOZ_FINAL : public RInstruction
|
||||
{
|
||||
private:
|
||||
|
@ -241,6 +241,11 @@ class JSObject : public js::ObjectImpl
|
||||
js::HandleShape shape,
|
||||
js::HandleTypeObject type);
|
||||
|
||||
static inline JSObject *copy(js::ExclusiveContext *cx,
|
||||
js::gc::AllocKind kind,
|
||||
js::gc::InitialHeap heap,
|
||||
js::HandleObject templateObject);
|
||||
|
||||
/* Make an array object with the specified initial state. */
|
||||
static inline js::ArrayObject *createArray(js::ExclusiveContext *cx,
|
||||
js::gc::AllocKind kind,
|
||||
|
@ -548,6 +548,35 @@ JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::Initi
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* static */ inline JSObject *
|
||||
JSObject::copy(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
|
||||
js::HandleObject templateObject)
|
||||
{
|
||||
js::RootedShape shape(cx, templateObject->lastProperty());
|
||||
js::RootedTypeObject type(cx, templateObject->type());
|
||||
MOZ_ASSERT(!templateObject->denseElementsAreCopyOnWrite());
|
||||
|
||||
JSObject *obj = create(cx, kind, heap, shape, type);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
size_t span = shape->slotSpan();
|
||||
if (span) {
|
||||
uint32_t numFixed = templateObject->numFixedSlots();
|
||||
const js::Value *fixed = &templateObject->getSlot(0);
|
||||
MOZ_ASSERT(numFixed <= span);
|
||||
obj->copySlotRange(0, fixed, numFixed);
|
||||
|
||||
if (numFixed < span) {
|
||||
uint32_t numSlots = span - numFixed;
|
||||
const js::Value *slots = &templateObject->getSlot(numFixed);
|
||||
obj->copySlotRange(numFixed, slots, numSlots);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* static */ inline JSObject *
|
||||
JSObject::createArrayInternal(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
|
||||
js::HandleShape shape, js::HandleTypeObject type)
|
||||
|
Loading…
Reference in New Issue
Block a user