Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (224937 => 224938)
--- trunk/Source/_javascript_Core/ChangeLog 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-11-16 23:44:12 UTC (rev 224938)
@@ -1,3 +1,62 @@
+2017-11-16 Saam Barati <sbar...@apple.com>
+
+ Add some X86 intrinsics to $vm to help with some perf testing
+ https://bugs.webkit.org/show_bug.cgi?id=179693
+
+ Reviewed by Mark Lam.
+
+ I've been doing some local perf testing of various ideas and have
+ had these come in handy. I'm going to land them to dollarVM to prevent
+ having to add them to my local build every time I do perf testing.
+
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::mfence):
+ (JSC::MacroAssemblerX86Common::rdtsc):
+ (JSC::MacroAssemblerX86Common::pause):
+ (JSC::MacroAssemblerX86Common::cpuid):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::rdtsc):
+ (JSC::X86Assembler::pause):
+ (JSC::X86Assembler::cpuid):
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::intrinsic):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGValidate.cpp:
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCPUIntrinsic):
+ * runtime/Intrinsic.cpp:
+ (JSC::intrinsicName):
+ * runtime/Intrinsic.h:
+ * tools/JSDollarVM.cpp:
+ (JSC::functionCpuMfence):
+ (JSC::functionCpuRdtsc):
+ (JSC::functionCpuCpuid):
+ (JSC::functionCpuPause):
+ (JSC::functionCpuClflush):
+ (JSC::JSDollarVM::finishCreation):
+
2017-11-16 JF Bastien <jfbast...@apple.com>
It should be easier to reify lazy property names
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (224937 => 224938)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -3880,6 +3880,26 @@
s_avxCheckState = (flags & (1 << 28)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
}
+ void mfence()
+ {
+ m_assembler.mfence();
+ }
+
+ void rdtsc()
+ {
+ m_assembler.rdtsc();
+ }
+
+ void pause()
+ {
+ m_assembler.pause();
+ }
+
+ void cpuid()
+ {
+ m_assembler.cpuid();
+ }
+
protected:
X86Assembler::Condition x86Condition(RelationalCondition cond)
{
Modified: trunk/Source/_javascript_Core/assembler/X86Assembler.h (224937 => 224938)
--- trunk/Source/_javascript_Core/assembler/X86Assembler.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/assembler/X86Assembler.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -260,6 +260,7 @@
OP_GROUP1A_Ev = 0x8F,
OP_NOP = 0x90,
OP_XCHG_EAX = 0x90,
+ OP_PAUSE = 0x90,
OP_CDQ = 0x99,
OP_MOV_EAXOv = 0xA1,
OP_MOV_OvEAX = 0xA3,
@@ -300,6 +301,7 @@
OP2_CVTTSD2SI_GdWsd = 0x2C,
OP2_CVTTSS2SI_GdWsd = 0x2C,
OP2_UCOMISD_VsdWsd = 0x2E,
+ OP2_RDTSC = 0x31,
OP2_3BYTE_ESCAPE_3A = 0x3A,
OP2_CMOVCC = 0x40,
OP2_ADDSD_VsdWsd = 0x58,
@@ -318,6 +320,7 @@
OP2_MOVD_EdVd = 0x7E,
OP2_JCC_rel32 = 0x80,
OP_SETCC = 0x90,
+ OP2_CPUID = 0xA2,
OP2_3BYTE_ESCAPE_AE = 0xAE,
OP2_IMUL_GvEv = 0xAF,
OP2_CMPXCHGb = 0xB0,
@@ -3544,6 +3547,22 @@
m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_MFENCE);
}
+ void rdtsc()
+ {
+ m_formatter.twoByteOp(OP2_RDTSC);
+ }
+
+ void pause()
+ {
+ m_formatter.prefix(PRE_SSE_F3);
+ m_formatter.oneByteOp(OP_PAUSE);
+ }
+
+ void cpuid()
+ {
+ m_formatter.twoByteOp(OP2_CPUID);
+ }
+
// Assembler admin methods:
size_t codeSize() const
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -3233,6 +3233,13 @@
m_state.setStructureClobberState(StructuresAreWatched);
break;
+ case CPUIntrinsic:
+ if (node->intrinsic() == CPURdtscIntrinsic)
+ forNode(node).setType(SpecInt32Only);
+ else
+ forNode(node).setType(SpecOther);
+ break;
+
case CheckTraps:
case LogShadowChickenPrologue:
case LogShadowChickenTail:
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -3037,6 +3037,23 @@
return true;
}
+ case CPUMfenceIntrinsic:
+ case CPURdtscIntrinsic:
+ case CPUCpuidIntrinsic:
+ case CPUPauseIntrinsic: {
+#if CPU(X86_64)
+ if (!isFTL(m_graph.m_plan.mode))
+ return false;
+ insertChecks();
+ set(VirtualRegister(resultOperand),
+ addToGraph(CPUIntrinsic, OpInfo(intrinsic), OpInfo()));
+ return true;
+#else
+ return false;
+#endif
+ }
+
+
default:
return false;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -437,6 +437,7 @@
case Switch:
case EntrySwitch:
case ForceOSRExit:
+ case CPUIntrinsic:
case CheckBadCell:
case Return:
case Unreachable:
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -200,6 +200,7 @@
case SuperSamplerBegin:
case SuperSamplerEnd:
case ForceOSRExit:
+ case CPUIntrinsic:
case CheckTraps:
case StringFromCharCode:
case MapHash:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -2133,6 +2133,7 @@
case CompareEqPtr:
case NumberToStringWithValidRadixConstant:
case GetGlobalThis:
+ case CPUIntrinsic:
break;
#else
default:
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -243,6 +243,8 @@
out.print(comma, inContext(node->structureSet().toStructureSet(), context));
if (node->hasStructure())
out.print(comma, inContext(*node->structure().get(), context));
+ if (node->op() == CPUIntrinsic)
+ out.print(comma, intrinsicName(node->intrinsic()));
if (node->hasTransition()) {
out.print(comma, pointerDumpInContext(node->transition(), context));
#if USE(JSVALUE64)
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -1442,6 +1442,12 @@
ASSERT(isEntrySwitch());
return m_opInfo.as<EntrySwitchData*>();
}
+
+ Intrinsic intrinsic()
+ {
+ RELEASE_ASSERT(op() == CPUIntrinsic);
+ return m_opInfo.as<Intrinsic>();
+ }
unsigned numSuccessors()
{
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -456,8 +456,12 @@
/* Metadata node that initializes the state for flushed argument types at an entrypoint in the program. */ \
/* Currently, we only use this for the blocks an EntrySwitch branches to at the root of the program. */ \
/* This is only used in SSA. */ \
- macro(InitializeEntrypointArguments, NodeMustGenerate)
+ macro(InitializeEntrypointArguments, NodeMustGenerate) \
+ \
+ /* Used for $vm performance debugging */ \
+ macro(CPUIntrinsic, NodeResultJS | NodeMustGenerate) \
+
// This enum generates a monotonically increasing id for all Node types,
// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
enum NodeType {
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -1042,6 +1042,14 @@
break;
}
+ case CPUIntrinsic: {
+ if (m_currentNode->intrinsic() == CPURdtscIntrinsic)
+ setPrediction(SpecInt32Only);
+ else
+ setPrediction(SpecOther);
+ break;
+ }
+
case PutByValAlias:
case DoubleAsInt32:
case GetLocalUnlinked:
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -352,6 +352,7 @@
case SuperSamplerBegin:
case SuperSamplerEnd:
case ForceOSRExit:
+ case CPUIntrinsic:
case CheckTraps:
case LogShadowChickenPrologue:
case LogShadowChickenTail:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -5665,6 +5665,7 @@
case IdentityWithProfile:
case InitializeEntrypointArguments:
case EntrySwitch:
+ case CPUIntrinsic:
DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -6135,6 +6135,7 @@
case PhantomSpread:
case PhantomNewArrayWithSpread:
case IdentityWithProfile:
+ case CPUIntrinsic:
DFG_CRASH(m_jit.graph(), node, "Unexpected node");
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -333,6 +333,19 @@
VALIDATE((node), type == Array::ArrayStorage || type == Array::SlowPutArrayStorage);
break;
}
+ case CPUIntrinsic: {
+ switch (node->intrinsic()) {
+ case CPUMfenceIntrinsic:
+ case CPURdtscIntrinsic:
+ case CPUCpuidIntrinsic:
+ case CPUPauseIntrinsic:
+ break;
+ default:
+ VALIDATE((node), false);
+ break;
+ }
+ break;
+ }
default:
break;
}
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -315,6 +315,7 @@
case AtomicsXor:
case AtomicsIsLockFree:
case InitializeEntrypointArguments:
+ case CPUIntrinsic:
// These are OK.
break;
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -1003,6 +1003,13 @@
case ForceOSRExit:
compileForceOSRExit();
break;
+ case CPUIntrinsic:
+#if CPU(X86_64)
+ compileCPUIntrinsic();
+#else
+ RELEASE_ASSERT_NOT_REACHED();
+#endif
+ break;
case Throw:
compileThrow();
break;
@@ -8190,6 +8197,53 @@
{
terminate(InadequateCoverage);
}
+
+ void compileCPUIntrinsic()
+ {
+#if CPU(X86_64)
+ Intrinsic intrinsic = m_node->intrinsic();
+ switch (intrinsic) {
+ case CPUMfenceIntrinsic:
+ case CPUCpuidIntrinsic:
+ case CPUPauseIntrinsic: {
+ PatchpointValue* patchpoint = m_out.patchpoint(Void);
+ patchpoint->effects = Effects::forCall();
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
+ switch (intrinsic) {
+ case CPUMfenceIntrinsic:
+ jit.mfence();
+ break;
+ case CPUCpuidIntrinsic:
+ jit.cpuid();
+ break;
+ case CPUPauseIntrinsic:
+ jit.pause();
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ });
+ setJSValue(m_out.constInt64(JSValue::encode(jsUndefined())));
+ break;
+ }
+ case CPURdtscIntrinsic: {
+ PatchpointValue* patchpoint = m_out.patchpoint(Int32);
+ patchpoint->effects = Effects::forCall();
+ patchpoint->clobber(RegisterSet { X86Registers::eax, X86Registers::edx });
+ // The low 32-bits of rdtsc go into rax.
+ patchpoint->resultConstraint = ValueRep::reg(X86Registers::eax);
+ patchpoint->setGenerator( [=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
+ jit.rdtsc();
+ });
+ setJSValue(boxInt32(patchpoint));
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+
+ }
+#endif
+ }
void compileThrow()
{
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -209,6 +209,14 @@
return "CheckInt32Intrinsic";
case FiatInt52Intrinsic:
return "FiatInt52Intrinsic";
+ case CPUMfenceIntrinsic:
+ return "CPUMfenceIntrinsic";
+ case CPURdtscIntrinsic:
+ return "CPURdtscIntrinsic";
+ case CPUCpuidIntrinsic:
+ return "CPUCpuidIntrinsic";
+ case CPUPauseIntrinsic:
+ return "CPUPauseIntrinsic";
}
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (224937 => 224938)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2017-11-16 23:44:12 UTC (rev 224938)
@@ -122,6 +122,12 @@
SetInt32HeapPredictionIntrinsic,
CheckInt32Intrinsic,
FiatInt52Intrinsic,
+
+ // These are used for $vm performance debugging features.
+ CPUMfenceIntrinsic,
+ CPURdtscIntrinsic,
+ CPUCpuidIntrinsic,
+ CPUPauseIntrinsic,
};
const char* intrinsicName(Intrinsic);
Modified: trunk/Source/_javascript_Core/tools/JSDollarVM.cpp (224937 => 224938)
--- trunk/Source/_javascript_Core/tools/JSDollarVM.cpp 2017-11-16 23:27:59 UTC (rev 224937)
+++ trunk/Source/_javascript_Core/tools/JSDollarVM.cpp 2017-11-16 23:44:12 UTC (rev 224938)
@@ -28,8 +28,10 @@
#include "CodeBlock.h"
#include "FunctionCodeBlock.h"
+#include "JSArrayBuffer.h"
#include "JSCInlines.h"
#include "VMInspector.h"
+#include <wtf/Atomics.h>
#include <wtf/DataLog.h>
#include <wtf/ProcessID.h>
#include <wtf/StringPrintStream.h>
@@ -59,6 +61,97 @@
return JSValue::encode(jsBoolean(false));
}
+static EncodedJSValue JSC_HOST_CALL functionCpuMfence(ExecState*)
+{
+#if CPU(X86_64) && !OS(WINDOWS)
+ asm volatile("mfence" ::: "memory");
+#endif
+ return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL functionCpuRdtsc(ExecState*)
+{
+#if CPU(X86_64) && !OS(WINDOWS)
+ unsigned high;
+ unsigned low;
+ asm volatile ("rdtsc" : "=a"(low), "=d"(high));
+ return JSValue::encode(jsNumber(low));
+#else
+ return JSValue::encode(jsNumber(0));
+#endif
+}
+
+static EncodedJSValue JSC_HOST_CALL functionCpuCpuid(ExecState*)
+{
+#if CPU(X86_64) && !OS(WINDOWS)
+ WTF::x86_cpuid();
+#endif
+ return JSValue::encode(jsUndefined());
+}
+
+static EncodedJSValue JSC_HOST_CALL functionCpuPause(ExecState*)
+{
+#if CPU(X86_64) && !OS(WINDOWS)
+ asm volatile ("pause" ::: "memory");
+#endif
+ return JSValue::encode(jsUndefined());
+}
+
+// This takes either a JSArrayBuffer, JSArrayBufferView*, or any other object as its first
+// argument. The second argument is expected to be an integer.
+//
+// If the first argument is a JSArrayBuffer, it'll clflush on that buffer
+// plus the second argument as a byte offset. It'll also flush on the object
+// itself so its length, etc, aren't in the cache.
+//
+// If the first argument is not a JSArrayBuffer, we load the butterfly
+// and clflush at the address of the butterfly.
+static EncodedJSValue JSC_HOST_CALL functionCpuClflush(ExecState* exec)
+{
+#if CPU(X86_64) && !OS(WINDOWS)
+ VM& vm = exec->vm();
+
+ if (!exec->argument(1).isInt32())
+ return JSValue::encode(jsBoolean(false));
+
+ auto clflush = [] (void* ptr) {
+ char* ptrToFlush = static_cast<char*>(ptr);
+ asm volatile ("clflush %0" :: "m"(*ptrToFlush) : "memory");
+ };
+
+ uint32_t offset = exec->argument(1).asUInt32();
+
+ char* ptr = nullptr;
+ if (JSArrayBuffer* buffer = jsDynamicCast<JSArrayBuffer*>(vm, exec->argument(0))) {
+ if (ArrayBuffer* impl = buffer->impl()) {
+ if (offset < impl->byteLength()) {
+ clflush(impl);
+ ptr = bitwise_cast<char*>(impl) + offset;
+ }
+ }
+ } else if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, exec->argument(0)))
+ ptr = bitwise_cast<char*>(view);
+ else if (JSObject* object = jsDynamicCast<JSObject*>(vm, exec->argument(0))) {
+ switch (object->indexingType()) {
+ case ALL_INT32_INDEXING_TYPES:
+ case ALL_CONTIGUOUS_INDEXING_TYPES:
+ case ALL_DOUBLE_INDEXING_TYPES:
+ clflush(object);
+ ptr = bitwise_cast<char*>(object->butterfly()) + offset;
+ }
+ }
+
+ if (!ptr)
+ return JSValue::encode(jsBoolean(false));
+
+ clflush(ptr);
+ return JSValue::encode(jsBoolean(true));
+#else
+ UNUSED_PARAM(exec);
+ return JSValue::encode(jsBoolean(false));
+#endif
+}
+
class CallerFrameJITTypeFunctor {
public:
CallerFrameJITTypeFunctor()
@@ -270,6 +363,12 @@
addFunction(vm, globalObject, "crash", functionCrash, 0);
putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
+
+ putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuMfence"), 0, functionCpuMfence, CPUMfenceIntrinsic, 0);
+ putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuRdtsc"), 0, functionCpuRdtsc, CPURdtscIntrinsic, 0);
+ putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, 0);
+ putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, 0);
+ addFunction(vm, globalObject, "cpuClflush", functionCpuClflush, 2);
addFunction(vm, globalObject, "llintTrue", functionLLintTrue, 0);
addFunction(vm, globalObject, "jitTrue", functionJITTrue, 0);