Bug 892634 - Part 2: Compile bit ops on values for parallel execution. (r=nmatsakis)

This commit is contained in:
Shu-yu Guo 2013-08-02 08:24:57 -07:00
parent cdf0bb59a4
commit fee7d552f7
4 changed files with 114 additions and 15 deletions

View File

@ -6135,7 +6135,10 @@ CodeGenerator::visitThrow(LThrow *lir)
}
typedef bool (*BitNotFn)(JSContext *, HandleValue, int *p);
static const VMFunction BitNotInfo = FunctionInfo<BitNotFn>(BitNot);
typedef ParallelResult (*BitNotParFn)(ForkJoinSlice *, HandleValue, int32_t *);
static const VMFunctionsModal BitNotInfo = VMFunctionsModal(
FunctionInfo<BitNotFn>(BitNot),
FunctionInfo<BitNotParFn>(BitNotPar));
bool
CodeGenerator::visitBitNotV(LBitNotV *lir)
@ -6145,11 +6148,22 @@ CodeGenerator::visitBitNotV(LBitNotV *lir)
}
typedef bool (*BitopFn)(JSContext *, HandleValue, HandleValue, int *p);
static const VMFunction BitAndInfo = FunctionInfo<BitopFn>(BitAnd);
static const VMFunction BitOrInfo = FunctionInfo<BitopFn>(BitOr);
static const VMFunction BitXorInfo = FunctionInfo<BitopFn>(BitXor);
static const VMFunction BitLhsInfo = FunctionInfo<BitopFn>(BitLsh);
static const VMFunction BitRhsInfo = FunctionInfo<BitopFn>(BitRsh);
typedef ParallelResult (*BitopParFn)(ForkJoinSlice *, HandleValue, HandleValue, int32_t *);
static const VMFunctionsModal BitAndInfo = VMFunctionsModal(
FunctionInfo<BitopFn>(BitAnd),
FunctionInfo<BitopParFn>(BitAndPar));
static const VMFunctionsModal BitOrInfo = VMFunctionsModal(
FunctionInfo<BitopFn>(BitOr),
FunctionInfo<BitopParFn>(BitOrPar));
static const VMFunctionsModal BitXorInfo = VMFunctionsModal(
FunctionInfo<BitopFn>(BitXor),
FunctionInfo<BitopParFn>(BitXorPar));
static const VMFunctionsModal BitLhsInfo = VMFunctionsModal(
FunctionInfo<BitopFn>(BitLsh),
FunctionInfo<BitopParFn>(BitLshPar));
static const VMFunctionsModal BitRhsInfo = VMFunctionsModal(
FunctionInfo<BitopFn>(BitRsh),
FunctionInfo<BitopParFn>(BitRshPar));
bool
CodeGenerator::visitBitOpV(LBitOpV *lir)

View File

@ -391,6 +391,79 @@ js::ion::StringsUnequalPar(ForkJoinSlice *slice, HandleString v1, HandleString v
return StringsEqualImplPar<false>(slice, v1, v2, res);
}
ParallelResult
ion::BitNotPar(ForkJoinSlice *slice, HandleValue in, int32_t *out)
{
if (in.isObject())
return TP_RETRY_SEQUENTIALLY;
int i;
if (!NonObjectToInt32(slice, in, &i))
return TP_FATAL;
*out = ~i;
return TP_SUCCESS;
}
#define BIT_OP(OP) \
JS_BEGIN_MACRO \
int32_t left, right; \
if (lhs.isObject() || rhs.isObject()) \
return TP_RETRY_SEQUENTIALLY; \
if (!NonObjectToInt32(slice, lhs, &left) || \
!NonObjectToInt32(slice, rhs, &right)) \
{ \
return TP_FATAL; \
} \
*out = (OP); \
return TP_SUCCESS; \
JS_END_MACRO
ParallelResult
ion::BitXorPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out)
{
BIT_OP(left ^ right);
}
ParallelResult
ion::BitOrPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out)
{
BIT_OP(left | right);
}
ParallelResult
ion::BitAndPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out)
{
BIT_OP(left & right);
}
ParallelResult
ion::BitLshPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out)
{
BIT_OP(left << (right & 31));
}
ParallelResult
ion::BitRshPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out)
{
BIT_OP(left >> (right & 31));
}
#undef BIT_OP
ParallelResult
ion::UrshValuesPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs,
MutableHandleValue out)
{
uint32_t left;
int32_t right;
if (lhs.isObject() || rhs.isObject())
return TP_RETRY_SEQUENTIALLY;
if (!NonObjectToUint32(slice, lhs, &left) || !NonObjectToInt32(slice, rhs, &right))
return TP_FATAL;
left >>= right & 31;
out.setNumber(uint32_t(left));
return TP_SUCCESS;
}
void
ion::AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *currentScript,
jsbytecode *bytecode)

View File

@ -45,8 +45,8 @@ ParallelResult ConcatStringsPar(ForkJoinSlice *slice, HandleString left, HandleS
ParallelResult IntToStringPar(ForkJoinSlice *slice, int i, MutableHandleString out);
ParallelResult DoubleToStringPar(ForkJoinSlice *slice, double d, MutableHandleString out);
// These parallel operations fail if they would be required to convert
// to a string etc etc.
// Binary and unary operator functions on values. These tend to return
// RETRY_SEQUENTIALLY if the values are objects.
ParallelResult StrictlyEqualPar(ForkJoinSlice *slice, MutableHandleValue v1, MutableHandleValue v2, bool *);
ParallelResult StrictlyUnequalPar(ForkJoinSlice *slice, MutableHandleValue v1, MutableHandleValue v2, bool *);
ParallelResult LooselyEqualPar(ForkJoinSlice *slice, MutableHandleValue v1, MutableHandleValue v2, bool *);
@ -59,10 +59,22 @@ ParallelResult GreaterThanOrEqualPar(ForkJoinSlice *slice, MutableHandleValue v1
ParallelResult StringsEqualPar(ForkJoinSlice *slice, HandleString v1, HandleString v2, bool *);
ParallelResult StringsUnequalPar(ForkJoinSlice *slice, HandleString v1, HandleString v2, bool *);
ParallelResult BitNotPar(ForkJoinSlice *slice, HandleValue in, int32_t *out);
ParallelResult BitXorPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out);
ParallelResult BitOrPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out);
ParallelResult BitAndPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out);
ParallelResult BitLshPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out);
ParallelResult BitRshPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs, int32_t *out);
ParallelResult UrshValuesPar(ForkJoinSlice *slice, HandleValue lhs, HandleValue rhs,
MutableHandleValue out);
// Make a new rest parameter in parallel.
ParallelResult InitRestParameterPar(ForkJoinSlice *slice, uint32_t length, Value *rest,
HandleObject templateObj, HandleObject res,
MutableHandleObject out);
// Abort and debug tracing functions.
void AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *currentScript,
jsbytecode *bytecode);
void PropagateAbortPar(JSScript *outermostScript, JSScript *currentScript);

View File

@ -138,15 +138,15 @@ class ParallelSafetyVisitor : public MInstructionVisitor
UNSAFE_OP(GetDynamicName)
UNSAFE_OP(FilterArguments)
UNSAFE_OP(CallDirectEval)
SPECIALIZED_OP(BitNot, PERMIT_INT32)
SAFE_OP(BitNot)
UNSAFE_OP(TypeOf)
SAFE_OP(ToId)
SPECIALIZED_OP(BitAnd, PERMIT_INT32)
SPECIALIZED_OP(BitOr, PERMIT_INT32)
SPECIALIZED_OP(BitXor, PERMIT_INT32)
SPECIALIZED_OP(Lsh, PERMIT_INT32)
SPECIALIZED_OP(Rsh, PERMIT_INT32)
SPECIALIZED_OP(Ursh, PERMIT_NUMERIC)
SAFE_OP(BitAnd)
SAFE_OP(BitOr)
SAFE_OP(BitXor)
SAFE_OP(Lsh)
SAFE_OP(Rsh)
SAFE_OP(Ursh)
SPECIALIZED_OP(MinMax, PERMIT_NUMERIC)
SAFE_OP(Abs)
SAFE_OP(Sqrt)