Bug 1200809 part 4 - Convert Atomics natives to new InlinableNatives system. r=lth

This commit is contained in:
Jan de Mooij 2015-09-04 15:55:09 +02:00
parent 6335b6f2da
commit 1d19fc47e0
4 changed files with 65 additions and 46 deletions

View File

@ -55,6 +55,7 @@
#include "asmjs/AsmJSModule.h"
#include "jit/AtomicOperations.h"
#include "jit/InlinableNatives.h"
#include "js/Class.h"
#include "vm/GlobalObject.h"
#include "vm/SharedTypedArrayObject.h"
@ -1214,20 +1215,20 @@ js::FutexRuntime::wake(WakeReason reason)
}
const JSFunctionSpec AtomicsMethods[] = {
JS_FN("compareExchange", atomics_compareExchange, 4,0),
JS_FN("load", atomics_load, 2,0),
JS_FN("store", atomics_store, 3,0),
JS_FN("exchange", atomics_exchange, 3,0),
JS_FN("fence", atomics_fence, 0,0),
JS_FN("add", atomics_add, 3,0),
JS_FN("sub", atomics_sub, 3,0),
JS_FN("and", atomics_and, 3,0),
JS_FN("or", atomics_or, 3,0),
JS_FN("xor", atomics_xor, 3,0),
JS_FN("isLockFree", atomics_isLockFree, 1,0),
JS_FN("futexWait", atomics_futexWait, 4,0),
JS_FN("futexWake", atomics_futexWake, 3,0),
JS_FN("futexWakeOrRequeue", atomics_futexWakeOrRequeue, 5,0),
JS_INLINABLE_FN("compareExchange", atomics_compareExchange, 4,0, AtomicsCompareExchange),
JS_INLINABLE_FN("load", atomics_load, 2,0, AtomicsLoad),
JS_INLINABLE_FN("store", atomics_store, 3,0, AtomicsStore),
JS_INLINABLE_FN("exchange", atomics_exchange, 3,0, AtomicsExchange),
JS_INLINABLE_FN("fence", atomics_fence, 0,0, AtomicsFence),
JS_INLINABLE_FN("add", atomics_add, 3,0, AtomicsAdd),
JS_INLINABLE_FN("sub", atomics_sub, 3,0, AtomicsSub),
JS_INLINABLE_FN("and", atomics_and, 3,0, AtomicsAnd),
JS_INLINABLE_FN("or", atomics_or, 3,0, AtomicsOr),
JS_INLINABLE_FN("xor", atomics_xor, 3,0, AtomicsXor),
JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1,0, AtomicsIsLockFree),
JS_FN("futexWait", atomics_futexWait, 4,0),
JS_FN("futexWake", atomics_futexWake, 3,0),
JS_FN("futexWakeOrRequeue", atomics_futexWakeOrRequeue, 5,0),
JS_FS_END
};

View File

@ -16,6 +16,18 @@
_(ArraySlice) \
_(ArraySplice) \
\
_(AtomicsCompareExchange) \
_(AtomicsExchange) \
_(AtomicsLoad) \
_(AtomicsStore) \
_(AtomicsFence) \
_(AtomicsAdd) \
_(AtomicsSub) \
_(AtomicsAnd) \
_(AtomicsOr) \
_(AtomicsXor) \
_(AtomicsIsLockFree) \
\
_(MathAbs) \
_(MathFloor) \
_(MathCeil) \

View File

@ -28,6 +28,8 @@ class CodeGenerator;
class CallInfo;
class BaselineFrameInspector;
enum class InlinableNative : uint16_t;
// Records information about a baseline frame for compilation that is stable
// when later used off thread.
BaselineFrameInspector*
@ -801,7 +803,7 @@ class IonBuilder
InliningStatus inlineAtomicsLoad(CallInfo& callInfo);
InliningStatus inlineAtomicsStore(CallInfo& callInfo);
InliningStatus inlineAtomicsFence(CallInfo& callInfo);
InliningStatus inlineAtomicsBinop(CallInfo& callInfo, JSFunction* target);
InliningStatus inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target);
InliningStatus inlineAtomicsIsLockFree(CallInfo& callInfo);
// Slot intrinsics.

View File

@ -56,28 +56,6 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return InliningStatus_NotInlined;
}
// Atomic natives.
if (native == atomics_compareExchange)
return inlineAtomicsCompareExchange(callInfo);
if (native == atomics_exchange)
return inlineAtomicsExchange(callInfo);
if (native == atomics_load)
return inlineAtomicsLoad(callInfo);
if (native == atomics_store)
return inlineAtomicsStore(callInfo);
if (native == atomics_fence)
return inlineAtomicsFence(callInfo);
if (native == atomics_add ||
native == atomics_sub ||
native == atomics_and ||
native == atomics_or ||
native == atomics_xor)
{
return inlineAtomicsBinop(callInfo, target);
}
if (native == atomics_isLockFree)
return inlineAtomicsIsLockFree(callInfo);
if (native == ArrayConstructor)
return inlineArray(callInfo);
@ -325,7 +303,7 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return InliningStatus_NotInlined;
}
switch (target->jitInfo()->inlinableNative) {
switch (InlinableNative inlNative = target->jitInfo()->inlinableNative) {
// Array natives.
case InlinableNative::ArrayIsArray:
return inlineArrayIsArray(callInfo);
@ -342,6 +320,26 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
case InlinableNative::ArraySplice:
return inlineArraySplice(callInfo);
// Atomic natives.
case InlinableNative::AtomicsCompareExchange:
return inlineAtomicsCompareExchange(callInfo);
case InlinableNative::AtomicsExchange:
return inlineAtomicsExchange(callInfo);
case InlinableNative::AtomicsLoad:
return inlineAtomicsLoad(callInfo);
case InlinableNative::AtomicsStore:
return inlineAtomicsStore(callInfo);
case InlinableNative::AtomicsFence:
return inlineAtomicsFence(callInfo);
case InlinableNative::AtomicsAdd:
case InlinableNative::AtomicsSub:
case InlinableNative::AtomicsAnd:
case InlinableNative::AtomicsOr:
case InlinableNative::AtomicsXor:
return inlineAtomicsBinop(callInfo, inlNative);
case InlinableNative::AtomicsIsLockFree:
return inlineAtomicsIsLockFree(callInfo);
// Math natives.
case InlinableNative::MathAbs:
return inlineMathAbs(callInfo);
@ -2987,7 +2985,7 @@ IonBuilder::inlineAtomicsFence(CallInfo& callInfo)
}
IonBuilder::InliningStatus
IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, JSFunction* target)
IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target)
{
if (callInfo.argc() != 3 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
@ -3008,20 +3006,26 @@ IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, JSFunction* target)
MDefinition* index;
atomicsCheckBounds(callInfo, &elements, &index);
JSNative native = target->native();
AtomicOp k = AtomicFetchAddOp;
if (native == atomics_add)
switch (target) {
case InlinableNative::AtomicsAdd:
k = AtomicFetchAddOp;
else if (native == atomics_sub)
break;
case InlinableNative::AtomicsSub:
k = AtomicFetchSubOp;
else if (native == atomics_and)
break;
case InlinableNative::AtomicsAnd:
k = AtomicFetchAndOp;
else if (native == atomics_or)
break;
case InlinableNative::AtomicsOr:
k = AtomicFetchOrOp;
else if (native == atomics_xor)
break;
case InlinableNative::AtomicsXor:
k = AtomicFetchXorOp;
else
break;
default:
MOZ_CRASH("Bad atomic operation");
}
MAtomicTypedArrayElementBinop* binop =
MAtomicTypedArrayElementBinop::New(alloc(), k, elements, index, arrayType, value);