diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/dfg/DFGJITCode.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGJITCode.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGJITCode.cpp | 86 |
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) |