Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (233657 => 233658)
--- trunk/Source/_javascript_Core/ChangeLog 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-07-09 21:55:48 UTC (rev 233658)
@@ -1,3 +1,43 @@
+2018-07-09 Mark Lam <[email protected]>
+
+ Add --traceLLIntExecution and --traceLLIntSlowPath options.
+ https://bugs.webkit.org/show_bug.cgi?id=187479
+
+ Reviewed by Yusuke Suzuki and Saam Barati.
+
+ These options are only available if LLINT_TRACING is enabled in LLIntCommon.h.
+
+ The details:
+ 1. LLINT_TRACING consolidates and replaces LLINT_EXECUTION_TRACING and LLINT_SLOW_PATH_TRACING.
+ 2. Tracing is now guarded behind runtime options --traceLLIntExecution and --traceLLIntSlowPath.
+ This makes it such that enabling LLINT_TRACING doesn't means that we'll
+ continually spammed with logging until we rebuild.
+ 3. Fixed slow path LLINT tracing to work with exception check validation.
+
+ * llint/LLIntCommon.h:
+ * llint/LLIntExceptions.cpp:
+ (JSC::LLInt::returnToThrow):
+ (JSC::LLInt::callToThrow):
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::slowPathLog):
+ (JSC::LLInt::slowPathLn):
+ (JSC::LLInt::slowPathLogF):
+ (JSC::LLInt::slowPathLogLn):
+ (JSC::LLInt::llint_trace_operand):
+ (JSC::LLInt::llint_trace_value):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::traceFunctionPrologue):
+ (JSC::LLInt::handleHostCall):
+ (JSC::LLInt::setUpCall):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+ * runtime/CommonSlowPathsExceptions.cpp:
+ (JSC::CommonSlowPaths::interpreterThrowInCaller):
+ * runtime/Options.cpp:
+ (JSC::Options::isAvailable):
+ * runtime/Options.h:
+
2018-07-09 Yusuke Suzuki <[email protected]>
[JSC] Embed RegExp into constant buffer in UnlinkedCodeBlock and CodeBlock
Modified: trunk/Source/_javascript_Core/llint/LLIntCommon.h (233657 => 233658)
--- trunk/Source/_javascript_Core/llint/LLIntCommon.h 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/llint/LLIntCommon.h 2018-07-09 21:55:48 UTC (rev 233658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,12 +25,12 @@
#pragma once
-// Print every instruction executed.
-#define LLINT_EXECUTION_TRACING 0
+// Enables LLINT tracing.
+// - Prints every instruction executed if Options::traceLLIntExecution() is enabled.
+// - Prints some information for some of the more subtle slow paths if
+// Options::traceLLIntSlowPath() is enabled.
+#define LLINT_TRACING 0
-// Print some information for some of the more subtle slow paths.
-#define LLINT_SLOW_PATH_TRACING 0
-
// Disable inline allocation in the interpreter. This is great if you're changing
// how the GC allocates.
#if ENABLE(ALLOCATION_LOGGING)
Modified: trunk/Source/_javascript_Core/llint/LLIntExceptions.cpp (233657 => 233658)
--- trunk/Source/_javascript_Core/llint/LLIntExceptions.cpp 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/llint/LLIntExceptions.cpp 2018-07-09 21:55:48 UTC (rev 233658)
@@ -33,7 +33,7 @@
#include "LowLevelInterpreter.h"
#include "JSCInlines.h"
-#if LLINT_SLOW_PATH_TRACING
+#if LLINT_TRACING
#include "Exception.h"
#endif
@@ -42,10 +42,12 @@
Instruction* returnToThrow(ExecState* exec)
{
UNUSED_PARAM(exec);
-#if LLINT_SLOW_PATH_TRACING
- VM* vm = &exec->vm();
- auto scope = DECLARE_THROW_SCOPE(*vm);
- dataLog("Throwing exception ", JSValue(scope.exception()), " (returnToThrow).\n");
+#if LLINT_TRACING
+ if (UNLIKELY(Options::traceLLIntSlowPath())) {
+ VM* vm = &exec->vm();
+ auto scope = DECLARE_CATCH_SCOPE(*vm);
+ dataLog("Throwing exception ", JSValue(scope.exception()), " (returnToThrow).\n");
+ }
#endif
return LLInt::exceptionInstructions();
}
@@ -53,10 +55,12 @@
void* callToThrow(ExecState* exec)
{
UNUSED_PARAM(exec);
-#if LLINT_SLOW_PATH_TRACING
- VM* vm = &exec->vm();
- auto scope = DECLARE_THROW_SCOPE(*vm);
- dataLog("Throwing exception ", JSValue(scope.exception()), " (callToThrow).\n");
+#if LLINT_TRACING
+ if (UNLIKELY(Options::traceLLIntSlowPath())) {
+ VM* vm = &exec->vm();
+ auto scope = DECLARE_CATCH_SCOPE(*vm);
+ dataLog("Throwing exception ", JSValue(scope.exception()), " (callToThrow).\n");
+ }
#endif
return LLInt::getCodePtr<ExceptionHandlerPtrTag>(llint_throw_during_call_trampoline).executableAddress();
}
Modified: trunk/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h (233657 => 233658)
--- trunk/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h 2018-07-09 21:55:48 UTC (rev 233658)
@@ -163,10 +163,10 @@
#define OFFLINE_ASM_BIG_ENDIAN 0
#endif
-#if LLINT_EXECUTION_TRACING
-#define OFFLINE_ASM_EXECUTION_TRACING 1
+#if LLINT_TRACING
+#define OFFLINE_ASM_TRACING 1
#else
-#define OFFLINE_ASM_EXECUTION_TRACING 0
+#define OFFLINE_ASM_TRACING 0
#endif
#if USE(POINTER_PROFILING)
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (233657 => 233658)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2018-07-09 21:55:48 UTC (rev 233658)
@@ -188,9 +188,49 @@
ExecState* __rcf_exec = (execCallee); \
LLINT_RETURN_TWO(pc, __rcf_exec); \
} while (false)
-
+
+#if LLINT_TRACING
+
+template<typename... Types>
+void slowPathLog(const Types&... values)
+{
+ dataLogIf(Options::traceLLIntSlowPath(), values...);
+}
+
+template<typename... Types>
+void slowPathLn(const Types&... values)
+{
+ dataLogLnIf(Options::traceLLIntSlowPath(), values...);
+}
+
+template<typename... Types>
+void slowPathLogF(const char* format, const Types&... values)
+{
+#if COMPILER(GCC_OR_CLANG)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#pragma GCC diagnostic ignored "-Wformat-security"
+#endif
+ if (Options::traceLLIntSlowPath())
+ dataLogF(format, values...);
+#if COMPILER(GCC_OR_CLANG)
+#pragma GCC diagnostic pop
+#endif
+}
+
+#else // not LLINT_TRACING
+
+template<typename... Types> void slowPathLog(const Types&...) { }
+template<typename... Types> void slowPathLogLn(const Types&...) { }
+template<typename... Types> void slowPathLogF(const char*, const Types&...) { }
+
+#endif // LLINT_TRACING
+
extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
{
+ if (!Options::traceLLIntExecution())
+ LLINT_END_IMPL();
+
LLINT_BEGIN();
dataLogF("<%p> %p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
&Thread::current(),
@@ -206,6 +246,9 @@
extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
{
+ if (!Options::traceLLIntExecution())
+ LLINT_END_IMPL();
+
JSValue value = LLINT_OP_C(operand).jsValue();
union {
struct {
@@ -233,18 +276,24 @@
LLINT_SLOW_PATH_DECL(trace_prologue)
{
+ if (!Options::traceLLIntExecution())
+ LLINT_END_IMPL();
+
dataLogF("<%p> %p / %p: in prologue of ", &Thread::current(), exec->codeBlock(), exec);
- dataLog(*exec->codeBlock(), "\n");
+ dataLog(exec->codeBlock(), "\n");
LLINT_END_IMPL();
}
static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
{
+ if (!Options::traceLLIntExecution())
+ return;
+
JSFunction* callee = jsCast<JSFunction*>(exec->jsCallee());
FunctionExecutable* executable = callee->jsExecutable();
CodeBlock* codeBlock = executable->codeBlockFor(kind);
dataLogF("<%p> %p / %p: in %s of ", &Thread::current(), codeBlock, exec, comment);
- dataLog(*codeBlock);
+ dataLog(codeBlock);
dataLogF(" function %p, executable %p; numVars = %u, numParameters = %u, numCalleeLocals = %u, caller = %p.\n",
callee, executable, codeBlock->numVars(), codeBlock->numParameters(), codeBlock->numCalleeLocals(), exec->callerFrame());
}
@@ -275,6 +324,9 @@
LLINT_SLOW_PATH_DECL(trace)
{
+ if (!Options::traceLLIntExecution())
+ LLINT_END_IMPL();
+
OpcodeID opcodeID = Interpreter::getOpcodeID(pc[0].u.opcode);
dataLogF("<%p> %p / %p: executing bc#%zu, %s, pc = %p\n",
&Thread::current(),
@@ -293,18 +345,6 @@
LLINT_END_IMPL();
}
-LLINT_SLOW_PATH_DECL(special_trace)
-{
- dataLogF("<%p> %p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
- &Thread::current(),
- exec->codeBlock(),
- exec,
- static_cast<intptr_t>(exec->codeBlock()->bytecodeOffset(pc)),
- Interpreter::getOpcodeID(pc[0].u.opcode),
- exec->returnPC().value());
- LLINT_END_IMPL();
-}
-
enum EntryKind { Prologue, ArityCheck };
#if ENABLE(JIT)
@@ -495,18 +535,18 @@
LLINT_SET_PC_FOR_STUBS();
-#if LLINT_SLOW_PATH_TRACING
- dataLogF("Checking stack height with exec = %p.\n", exec);
- dataLog("CodeBlock = ", *exec->codeBlock(), "\n");
- dataLogF("Num callee registers = %u.\n", exec->codeBlock()->numCalleeLocals());
- dataLogF("Num vars = %u.\n", exec->codeBlock()->numVars());
-
- dataLogF("Current OS stack end is at %p.\n", vm.softStackLimit());
+ CodeBlock* codeBlock = exec->codeBlock();
+ slowPathLogF("Checking stack height with exec = %p.\n", exec);
+ slowPathLog("CodeBlock = ", codeBlock, "\n");
+ if (codeBlock) {
+ slowPathLogF("Num callee registers = %u.\n", codeBlock->numCalleeLocals());
+ slowPathLogF("Num vars = %u.\n", codeBlock->numVars());
+ }
+ slowPathLogF("Current OS stack end is at %p.\n", vm.softStackLimit());
#if !ENABLE(JIT)
- dataLogF("Current C Loop stack end is at %p.\n", vm.cloopStackLimit());
+ slowPathLogF("Current C Loop stack end is at %p.\n", vm.cloopStackLimit());
#endif
-#endif
// If the stack check succeeds and we don't need to throw the error, then
// we'll return 0 instead. The prologue will check for a non-zero value
// when determining whether to set the callFrame or not.
@@ -1262,9 +1302,7 @@
LLINT_BEGIN();
CodeBlock* codeBlock = exec->codeBlock();
JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
-#if LLINT_SLOW_PATH_TRACING
- dataLogF("Creating function!\n");
-#endif
+ slowPathLogF("Creating function!\n");
LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
}
@@ -1273,9 +1311,7 @@
LLINT_BEGIN();
CodeBlock* codeBlock = exec->codeBlock();
JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
-#if LLINT_SLOW_PATH_TRACING
- dataLogF("Creating function!\n");
-#endif
+ slowPathLogF("Creating function!\n");
LLINT_RETURN(JSGeneratorFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
}
@@ -1284,9 +1320,7 @@
LLINT_BEGIN();
CodeBlock* codeBlock = exec->codeBlock();
JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
-#if LLINT_SLOW_PATH_TRACING
- dataLogF("Creating async function!\n");
-#endif
+ slowPathLogF("Creating async function!\n");
LLINT_RETURN(JSAsyncFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
}
@@ -1295,9 +1329,7 @@
LLINT_BEGIN();
CodeBlock* codeBlock = exec->codeBlock();
JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
-#if LLINT_SLOW_PATH_TRACING
- dataLogF("Creating async generator function!\n");
-#endif
+ slowPathLogF("Creating async generator function!\n");
LLINT_RETURN(JSAsyncGeneratorFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
}
@@ -1358,9 +1390,7 @@
{
UNUSED_PARAM(pc);
-#if LLINT_SLOW_PATH_TRACING
- dataLog("Performing host call.\n");
-#endif
+ slowPathLog("Performing host call.\n");
ExecState* exec = execCallee->callerFrame();
VM& vm = exec->vm();
@@ -1384,9 +1414,7 @@
LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue), CFunctionPtrTag);
}
-#if LLINT_SLOW_PATH_TRACING
- dataLog("Call callee is not a function: ", callee, "\n");
-#endif
+ slowPathLog("Call callee is not a function: ", callee, "\n");
ASSERT(callType == CallType::None);
LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
@@ -1408,9 +1436,7 @@
LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue), CFunctionPtrTag);
}
-#if LLINT_SLOW_PATH_TRACING
- dataLog("Constructor callee is not a function: ", callee, "\n");
-#endif
+ slowPathLog("Constructor callee is not a function: ", callee, "\n");
ASSERT(constructType == ConstructType::None);
LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
@@ -1422,9 +1448,7 @@
VM& vm = exec->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
-#if LLINT_SLOW_PATH_TRACING
- dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
-#endif
+ slowPathLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
if (!calleeAsFunctionCell) {
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h (233657 => 233658)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h 2018-07-09 21:55:48 UTC (rev 233658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,7 +52,6 @@
LLINT_SLOW_PATH_HIDDEN_DECL(trace_arityCheck_for_call);
LLINT_SLOW_PATH_HIDDEN_DECL(trace_arityCheck_for_construct);
LLINT_SLOW_PATH_HIDDEN_DECL(trace);
-LLINT_SLOW_PATH_HIDDEN_DECL(special_trace);
LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr);
LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_call);
LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_construct);
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (233657 => 233658)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2018-07-09 21:55:48 UTC (rev 233658)
@@ -839,7 +839,7 @@
end
macro traceExecution()
- if EXECUTION_TRACING
+ if TRACING
callSlowPath(_llint_trace)
end
end
@@ -1006,7 +1006,7 @@
tagReturnAddress sp
preserveCallerPCAndCFR()
- if EXECUTION_TRACING
+ if TRACING
subp maxFrameExtentForSlowPathCall, sp
callSlowPath(traceSlowPath)
addp maxFrameExtentForSlowPathCall, sp
Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPathsExceptions.cpp (233657 => 233658)
--- trunk/Source/_javascript_Core/runtime/CommonSlowPathsExceptions.cpp 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPathsExceptions.cpp 2018-07-09 21:55:48 UTC (rev 233658)
@@ -34,7 +34,7 @@
#include "LLIntCommon.h"
#include "JSCInlines.h"
-#if LLINT_SLOW_PATH_TRACING
+#if LLINT_TRACING
#include "Exception.h"
#endif
@@ -47,8 +47,9 @@
auto scope = DECLARE_THROW_SCOPE(*vm);
throwException(exec, scope, error);
-#if LLINT_SLOW_PATH_TRACING
- dataLog("Throwing exception ", JSValue(scope.exception()), ".\n");
+#if LLINT_TRACING
+ if (UNLIKELY(Options::traceLLIntSlowPath()))
+ dataLog("Throwing exception ", JSValue(scope.exception()), ".\n");
#endif
}
Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (233657 => 233658)
--- trunk/Source/_javascript_Core/runtime/Options.cpp 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp 2018-07-09 21:55:48 UTC (rev 233658)
@@ -27,6 +27,7 @@
#include "Options.h"
#include "AssemblerCommon.h"
+#include "LLIntCommon.h"
#include "MinimumReservedZoneSize.h"
#include "SigillCrashAnalyzer.h"
#include <algorithm>
@@ -158,6 +159,10 @@
if (id == useSigillCrashAnalyzerID)
return true;
#endif
+ if (id == traceLLIntExecutionID)
+ return !!LLINT_TRACING;
+ if (id == traceLLIntSlowPathID)
+ return !!LLINT_TRACING;
return false;
}
Modified: trunk/Source/_javascript_Core/runtime/Options.h (233657 => 233658)
--- trunk/Source/_javascript_Core/runtime/Options.h 2018-07-09 21:29:41 UTC (rev 233657)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2018-07-09 21:55:48 UTC (rev 233658)
@@ -513,7 +513,9 @@
v(bool, useArrayAllocationProfiling, true, Normal, "If true, we will use our normal array allocation profiling. If false, the allocation profile will always claim to be undecided.") \
v(bool, forcePolyProto, false, Normal, "If true, create_this will always create an object with a poly proto structure.") \
v(bool, forceMiniVMMode, false, Normal, "If true, it will force mini VM mode on.") \
- v(bool, useTracePoints, false, Normal, nullptr)
+ v(bool, useTracePoints, false, Normal, nullptr) \
+ v(bool, traceLLIntExecution, false, Configurable, nullptr) \
+ v(bool, traceLLIntSlowPath, false, Configurable, nullptr) \
enum OptionEquivalence {