Bug 997081 - Optimize StoreElementHole OOL VM call. r=bhackett

--HG--
extra : rebase_source : 110a92109994439c48300ddc88627c34fca27254
This commit is contained in:
Jan de Mooij 2014-04-16 17:24:23 +02:00
parent e40a4640ac
commit 23c31f2114
5 changed files with 68 additions and 9 deletions

View File

@ -5515,12 +5515,12 @@ CodeGenerator::visitStoreElementHoleV(LStoreElementHoleV *lir)
return true;
}
typedef bool (*SetObjectElementFn)(JSContext *, HandleObject, HandleValue, HandleValue,
bool strict);
typedef bool (*SetElementParFn)(ForkJoinContext *, HandleObject, HandleValue, HandleValue, bool);
static const VMFunctionsModal SetObjectElementInfo = VMFunctionsModal(
FunctionInfo<SetObjectElementFn>(SetObjectElement),
FunctionInfo<SetElementParFn>(SetElementPar));
typedef bool (*SetDenseElementFn)(JSContext *, HandleObject, int32_t, HandleValue,
bool strict);
typedef bool (*SetDenseElementParFn)(ForkJoinContext *, HandleObject, int32_t, HandleValue, bool);
static const VMFunctionsModal SetDenseElementInfo = VMFunctionsModal(
FunctionInfo<SetDenseElementFn>(SetDenseElement),
FunctionInfo<SetDenseElementParFn>(SetDenseElementPar));
bool
CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool)
@ -5600,11 +5600,11 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool)
pushArg(Imm32(current->mir()->strict()));
pushArg(value);
if (index->isConstant())
pushArg(*index->toConstant());
pushArg(Imm32(ToInt32(index)));
else
pushArg(TypedOrValueRegister(MIRType_Int32, ToAnyRegister(index)));
pushArg(ToRegister(index));
pushArg(object);
if (!callVM(SetObjectElementInfo, ins))
if (!callVM(SetDenseElementInfo, ins))
return false;
restoreLive(ins);
@ -6623,6 +6623,13 @@ CodeGenerator::visitCallGetElement(LCallGetElement *lir)
}
}
typedef bool (*SetObjectElementFn)(JSContext *, HandleObject, HandleValue, HandleValue,
bool strict);
typedef bool (*SetElementParFn)(ForkJoinContext *, HandleObject, HandleValue, HandleValue, bool);
static const VMFunctionsModal SetObjectElementInfo = VMFunctionsModal(
FunctionInfo<SetObjectElementFn>(SetObjectElement),
FunctionInfo<SetElementParFn>(SetElementPar));
bool
CodeGenerator::visitCallSetElement(LCallSetElement *lir)
{

View File

@ -276,6 +276,14 @@ jit::SetElementPar(ForkJoinContext *cx, HandleObject obj, HandleValue index, Han
return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, 0, &v, strict);
}
bool
jit::SetDenseElementPar(ForkJoinContext *cx, HandleObject obj, int32_t index, HandleValue value,
bool strict)
{
RootedValue indexVal(cx, Int32Value(index));
return SetElementPar(cx, obj, indexVal, value, strict);
}
JSString *
jit::ConcatStringsPar(ForkJoinContext *cx, HandleString left, HandleString right)
{

View File

@ -33,6 +33,8 @@ bool SetPropertyPar(ForkJoinContext *cx, HandleObject obj, HandlePropertyName na
HandleValue value, bool strict, jsbytecode *pc);
bool SetElementPar(ForkJoinContext *cx, HandleObject obj, HandleValue index,
HandleValue value, bool strict);
bool SetDenseElementPar(ForkJoinContext *cx, HandleObject obj, int32_t index,
HandleValue value, bool strict);
// String related parallel functions. These tend to call existing VM functions
// that take a ThreadSafeContext.

View File

@ -1037,6 +1037,45 @@ Recompile(JSContext *cx)
return true;
}
bool
SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue value,
bool strict)
{
// This function is called from Ion code for StoreElementHole's OOL path.
// In this case we know the object is native, has no indexed properties
// and we can use setDenseElement instead of setDenseElementWithType.
MOZ_ASSERT(obj->isNative());
MOZ_ASSERT(!obj->isIndexed());
JSObject::EnsureDenseResult result = JSObject::ED_SPARSE;
do {
if (index < 0)
break;
bool isArray = obj->is<ArrayObject>();
if (isArray && !obj->as<ArrayObject>().lengthIsWritable())
break;
uint32_t idx = uint32_t(index);
result = obj->ensureDenseElements(cx, idx, 1);
if (result != JSObject::ED_OK)
break;
if (isArray) {
ArrayObject &arr = obj->as<ArrayObject>();
if (idx >= arr.length())
arr.setLengthInt32(idx + 1);
}
obj->setDenseElement(idx, value);
return true;
} while (false);
if (result == JSObject::ED_FAILED)
return false;
MOZ_ASSERT(result == JSObject::ED_SPARSE);
RootedValue indexVal(cx, Int32Value(index));
return SetObjectElement(cx, obj, indexVal, value, strict);
}
#ifdef DEBUG
void
AssertValidObjectPtr(JSContext *cx, JSObject *obj)

View File

@ -677,6 +677,9 @@ JSString *RegExpReplace(JSContext *cx, HandleString string, HandleObject regexp,
JSString *StringReplace(JSContext *cx, HandleString string, HandleString pattern,
HandleString repl);
bool SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue value,
bool strict);
#ifdef DEBUG
void AssertValidObjectPtr(JSContext *cx, JSObject *obj);
void AssertValidStringPtr(JSContext *cx, JSString *str);