summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGJITCode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGJITCode.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCode.cpp86
1 files changed, 67 insertions, 19 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGJITCode.cpp b/Source/JavaScriptCore/dfg/DFGJITCode.cpp
index c53653f8f..7fb9f716c 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,11 +29,17 @@
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
+#include "JSCInlines.h"
+#include "TrackedReferences.h"
namespace JSC { namespace DFG {
JITCode::JITCode()
: DirectJITCode(DFGJIT)
+#if ENABLE(FTL_JIT)
+ , osrEntryRetry(0)
+ , abandonOSREntry(false)
+#endif // ENABLE(FTL_JIT)
{
}
@@ -77,30 +83,47 @@ void JITCode::reconstruct(
reconstruct(codeBlock, codeOrigin, streamIndex, recoveries);
result = Operands<JSValue>(OperandsLike, recoveries);
- for (size_t i = result.size(); i--;) {
- int operand = result.operandForIndex(i);
-
- if (operandIsArgument(operand)
- && !VirtualRegister(operand).toArgument()
- && codeBlock->codeType() == FunctionCode
- && codeBlock->specializationKind() == CodeForConstruct) {
- // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
- // also never be used. It doesn't matter what we put into the value for this,
- // but it has to be an actual value that can be grokked by subsequent DFG passes,
- // so we sanitize it here by turning it into Undefined.
- result[i] = jsUndefined();
- continue;
- }
-
+ for (size_t i = result.size(); i--;)
result[i] = recoveries[i].recover(exec);
+}
+
+RegisterSet JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock* codeBlock, CallSiteIndex callSiteIndex)
+{
+ for (OSRExit& exit : osrExit) {
+ if (exit.isExceptionHandler() && exit.m_exceptionHandlerCallSiteIndex.bits() == callSiteIndex.bits()) {
+ Operands<ValueRecovery> valueRecoveries;
+ reconstruct(codeBlock, exit.m_codeOrigin, exit.m_streamIndex, valueRecoveries);
+ RegisterSet liveAtOSRExit;
+ for (size_t index = 0; index < valueRecoveries.size(); ++index) {
+ const ValueRecovery& recovery = valueRecoveries[index];
+ if (recovery.isInRegisters()) {
+ if (recovery.isInGPR())
+ liveAtOSRExit.set(recovery.gpr());
+ else if (recovery.isInFPR())
+ liveAtOSRExit.set(recovery.fpr());
+#if USE(JSVALUE32_64)
+ else if (recovery.isInJSValueRegs()) {
+ liveAtOSRExit.set(recovery.payloadGPR());
+ liveAtOSRExit.set(recovery.tagGPR());
+ }
+#endif
+ else
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+
+ return liveAtOSRExit;
+ }
}
+
+ return RegisterSet();
}
#if ENABLE(FTL_JIT)
bool JITCode::checkIfOptimizationThresholdReached(CodeBlock* codeBlock)
{
ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
- return tierUpCounter.checkIfThresholdCrossedAndSet(codeBlock->baselineVersion());
+ return tierUpCounter.checkIfThresholdCrossedAndSet(codeBlock);
}
void JITCode::optimizeNextInvocation(CodeBlock* codeBlock)
@@ -108,7 +131,7 @@ void JITCode::optimizeNextInvocation(CodeBlock* codeBlock)
ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
if (Options::verboseOSR())
dataLog(*codeBlock, ": FTL-optimizing next invocation.\n");
- tierUpCounter.setNewThreshold(0, codeBlock->baselineVersion());
+ tierUpCounter.setNewThreshold(0, codeBlock);
}
void JITCode::dontOptimizeAnytimeSoon(CodeBlock* codeBlock)
@@ -138,7 +161,7 @@ void JITCode::optimizeSoon(CodeBlock* codeBlock)
CodeBlock* baseline = codeBlock->baselineVersion();
tierUpCounter.setNewThreshold(
baseline->adjustedCounterValue(Options::thresholdForFTLOptimizeSoon()),
- baseline);
+ codeBlock);
}
void JITCode::forceOptimizationSlowPathConcurrently(CodeBlock* codeBlock)
@@ -156,6 +179,7 @@ void JITCode::setOptimizationThresholdBasedOnCompilationResult(
switch (result) {
case CompilationSuccessful:
optimizeNextInvocation(codeBlock);
+ codeBlock->baselineVersion()->m_hasBeenCompiledWithFTL = true;
return;
case CompilationFailed:
dontOptimizeAnytimeSoon(codeBlock);
@@ -179,6 +203,30 @@ void JITCode::setOptimizationThresholdBasedOnCompilationResult(
}
#endif // ENABLE(FTL_JIT)
+void JITCode::validateReferences(const TrackedReferences& trackedReferences)
+{
+ common.validateReferences(trackedReferences);
+
+ for (OSREntryData& entry : osrEntry) {
+ for (unsigned i = entry.m_expectedValues.size(); i--;)
+ entry.m_expectedValues[i].validateReferences(trackedReferences);
+ }
+
+ minifiedDFG.validateReferences(trackedReferences);
+}
+
+std::optional<CodeOrigin> JITCode::findPC(CodeBlock*, void* pc)
+{
+ for (OSRExit& exit : osrExit) {
+ if (ExecutableMemoryHandle* handle = exit.m_code.executableMemory()) {
+ if (handle->start() <= pc && pc < handle->end())
+ return std::optional<CodeOrigin>(exit.m_codeOriginForExitProfile);
+ }
+ }
+
+ return std::nullopt;
+}
+
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)