Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (192844 => 192845)
--- trunk/Source/_javascript_Core/ChangeLog 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-12-01 00:55:32 UTC (rev 192845)
@@ -1,3 +1,43 @@
+2015-11-30 Saam barati <sbar...@apple.com>
+
+ FTL OSR Exits that are exception handlers should not have two different entrances. Instead, we should have two discrete OSR exits that do different things.
+ https://bugs.webkit.org/show_bug.cgi?id=151404
+
+ Reviewed by Filip Pizlo.
+
+ * ftl/FTLCompile.cpp:
+ (JSC::FTL::mmAllocateDataSection):
+ * ftl/FTLExceptionHandlerManager.cpp:
+ (JSC::FTL::ExceptionHandlerManager::addNewExit):
+ (JSC::FTL::ExceptionHandlerManager::addNewCallOperationExit):
+ (JSC::FTL::ExceptionHandlerManager::callOperationExceptionTarget):
+ (JSC::FTL::ExceptionHandlerManager::lazySlowPathExceptionTarget):
+ (JSC::FTL::ExceptionHandlerManager::callOperationOSRExit):
+ (JSC::FTL::ExceptionHandlerManager::getByIdOSRExit): Deleted.
+ (JSC::FTL::ExceptionHandlerManager::subOSRExit): Deleted.
+ * ftl/FTLExceptionHandlerManager.h:
+ * ftl/FTLExitThunkGenerator.cpp:
+ (JSC::FTL::ExitThunkGenerator::emitThunk):
+ * ftl/FTLOSRExit.cpp:
+ (JSC::FTL::OSRExitDescriptor::OSRExitDescriptor):
+ (JSC::FTL::OSRExitDescriptor::isExceptionHandler):
+ (JSC::FTL::OSRExit::OSRExit):
+ (JSC::FTL::OSRExit::spillRegistersToSpillSlot):
+ (JSC::FTL::OSRExit::recoverRegistersFromSpillSlot):
+ (JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
+ (JSC::FTL::OSRExit::willArriveAtOSRExitFromGenericUnwind):
+ (JSC::FTL::OSRExit::willArriveAtOSRExitFromCallOperation):
+ (JSC::FTL::OSRExit::needsRegisterRecoveryOnGenericUnwindOSRExitPath):
+ (JSC::FTL::OSRExitDescriptor::willArriveAtExitFromIndirectExceptionCheck): Deleted.
+ (JSC::FTL::OSRExitDescriptor::mightArriveAtOSRExitFromGenericUnwind): Deleted.
+ (JSC::FTL::OSRExitDescriptor::mightArriveAtOSRExitFromCallOperation): Deleted.
+ (JSC::FTL::OSRExitDescriptor::needsRegisterRecoveryOnGenericUnwindOSRExitPath): Deleted.
+ * ftl/FTLOSRExit.h:
+ * ftl/FTLOSRExitCompilationInfo.h:
+ (JSC::FTL::OSRExitCompilationInfo::OSRExitCompilationInfo):
+ * ftl/FTLOSRExitCompiler.cpp:
+ (JSC::FTL::compileFTLOSRExit):
+
2015-11-30 Mark Lam <mark....@apple.com>
Refactor the op_add, op_sub, and op_mul snippets to use the SnippetOperand class.
Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp 2015-12-01 00:55:32 UTC (rev 192845)
@@ -643,13 +643,40 @@
}
OSRExit& exit = state.jitCode->osrExit.last();
- if (exitDescriptor.willArriveAtExitFromIndirectExceptionCheck()) {
+ if (exit.willArriveAtExitFromIndirectExceptionCheck()) {
StackMaps::Record& record = iter->value[j].record;
RELEASE_ASSERT(exit.m_descriptor.m_semanticCodeOriginForCallFrameHeader.isSet());
CallSiteIndex callSiteIndex = state.jitCode->common.addUniqueCallSiteIndex(exit.m_descriptor.m_semanticCodeOriginForCallFrameHeader);
exit.m_exceptionHandlerCallSiteIndex = callSiteIndex;
- exceptionHandlerManager.addNewExit(iter->value[j].index, state.jitCode->osrExit.size() - 1);
+ OSRExit* callOperationExit = nullptr;
+ if (exitDescriptor.m_exceptionType == ExceptionType::SubGenerator) {
+ exceptionHandlerManager.addNewCallOperationExit(iter->value[j].index, state.jitCode->osrExit.size() - 1);
+ callOperationExit = &exit;
+ } else
+ exceptionHandlerManager.addNewExit(iter->value[j].index, state.jitCode->osrExit.size() - 1);
+
+ if (exitDescriptor.m_exceptionType == ExceptionType::GetById || exitDescriptor.m_exceptionType == ExceptionType::PutById) {
+ // We create two different OSRExits for GetById and PutById.
+ // One exit that will be arrived at from the genericUnwind exception handler path,
+ // and the other that will be arrived at from the callOperation exception handler path.
+ // This code here generates the second callOperation variant.
+ uint32_t stackmapRecordIndex = iter->value[j].index;
+ OSRExit exit(exitDescriptor, stackmapRecordIndex);
+ if (exitDescriptor.m_exceptionType == ExceptionType::GetById)
+ exit.m_exceptionType = ExceptionType::GetByIdCallOperation;
+ else
+ exit.m_exceptionType = ExceptionType::PutByIdCallOperation;
+ CallSiteIndex callSiteIndex = state.jitCode->common.addUniqueCallSiteIndex(exit.m_descriptor.m_semanticCodeOriginForCallFrameHeader);
+ exit.m_exceptionHandlerCallSiteIndex = callSiteIndex;
+
+ state.jitCode->osrExit.append(exit);
+ state.finalizer->osrExit.append(OSRExitCompilationInfo());
+
+ exceptionHandlerManager.addNewCallOperationExit(iter->value[j].index, state.jitCode->osrExit.size() - 1);
+ callOperationExit = &state.jitCode->osrExit.last();
+ }
+
// Subs and GetByIds have an interesting register preservation story,
// see comment below at GetById to read about it.
//
@@ -666,13 +693,13 @@
GPRReg result = record.locations[0].directGPR();
GPRReg base = record.locations[1].directGPR();
if (base == result)
- exit.registersToPreserveForCallThatMightThrow.set(base);
+ callOperationExit->registersToPreserveForCallThatMightThrow.set(base);
} else if (exitDescriptor.m_exceptionType == ExceptionType::SubGenerator) {
GPRReg result = record.locations[0].directGPR();
GPRReg left = record.locations[1].directGPR();
GPRReg right = record.locations[2].directGPR();
if (result == left || result == right)
- exit.registersToPreserveForCallThatMightThrow.set(result);
+ callOperationExit->registersToPreserveForCallThatMightThrow.set(result);
}
}
}
@@ -703,7 +730,7 @@
info.m_thunkAddress = linkBuffer->locationOf(info.m_thunkLabel);
exit.m_patchableCodeOffset = linkBuffer->offsetOf(info.m_thunkJump);
- if (exit.m_descriptor.mightArriveAtOSRExitFromGenericUnwind()) {
+ if (exit.willArriveAtOSRExitFromGenericUnwind()) {
HandlerInfo newHandler = exit.m_descriptor.m_baselineExceptionHandler;
newHandler.start = exit.m_exceptionHandlerCallSiteIndex.bits();
newHandler.end = exit.m_exceptionHandlerCallSiteIndex.bits() + 1;
@@ -781,7 +808,7 @@
// register that we would like to do value recovery on. We combat this situation from ever
// taking place by ensuring we spill the original base value and then recover it from
// the spill slot as the first step in OSR exit.
- if (OSRExit* exit = exceptionHandlerManager.getByIdOSRExit(iter->value[i].index))
+ if (OSRExit* exit = exceptionHandlerManager.callOperationOSRExit(iter->value[i].index))
exit->spillRegistersToSpillSlot(slowPathJIT, jsCallThatMightThrowSpillOffset);
}
MacroAssembler::Call call = callOperation(
@@ -900,7 +927,7 @@
if (result == left || result == right) {
// This situation has a really interesting register preservation story.
// See comment above for GetByIds.
- if (OSRExit* exit = exceptionHandlerManager.subOSRExit(iter->value[i].index))
+ if (OSRExit* exit = exceptionHandlerManager.callOperationOSRExit(iter->value[i].index))
exit->spillRegistersToSpillSlot(slowPathJIT, jsCallThatMightThrowSpillOffset);
}
@@ -1099,7 +1126,7 @@
OSRExit& exit = jitCode->osrExit[exitIndex];
Vector<const void*> codeAddresses;
- if (exit.m_descriptor.willArriveAtExitFromIndirectExceptionCheck()) // This jump doesn't happen directly from a patchpoint/stackmap we compile. It happens indirectly through an exception check somewhere.
+ if (exit.willArriveAtExitFromIndirectExceptionCheck()) // This jump doesn't happen directly from a patchpoint/stackmap we compile. It happens indirectly through an exception check somewhere.
continue;
StackMaps::Record& record = jitCode->stackmaps.records[exit.m_stackmapRecordIndex];
Modified: trunk/Source/_javascript_Core/ftl/FTLExceptionHandlerManager.cpp (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLExceptionHandlerManager.cpp 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLExceptionHandlerManager.cpp 2015-12-01 00:55:32 UTC (rev 192845)
@@ -41,9 +41,16 @@
{
m_map.add(stackmapRecordIndex, osrExitIndex);
OSRExit& exit = m_state.jitCode->osrExit[osrExitIndex];
- RELEASE_ASSERT(exit.m_descriptor.willArriveAtExitFromIndirectExceptionCheck());
+ RELEASE_ASSERT(exit.willArriveAtExitFromIndirectExceptionCheck());
}
+void ExceptionHandlerManager::addNewCallOperationExit(uint32_t stackmapRecordIndex, size_t osrExitIndex)
+{
+ m_callOperationMap.add(stackmapRecordIndex, osrExitIndex);
+ OSRExit& exit = m_state.jitCode->osrExit[osrExitIndex];
+ RELEASE_ASSERT(exit.willArriveAtExitFromIndirectExceptionCheck());
+}
+
CodeLocationLabel ExceptionHandlerManager::callOperationExceptionTarget(uint32_t stackmapRecordIndex)
{
#if FTL_USES_B3
@@ -51,15 +58,15 @@
RELEASE_ASSERT_NOT_REACHED();
return CodeLocationLabel();
#else // FTL_USES_B3
- auto findResult = m_map.find(stackmapRecordIndex);
- if (findResult == m_map.end())
+ auto findResult = m_callOperationMap.find(stackmapRecordIndex);
+ if (findResult == m_callOperationMap.end())
return CodeLocationLabel();
size_t osrExitIndex = findResult->value;
- RELEASE_ASSERT(m_state.jitCode->osrExit[osrExitIndex].m_descriptor.mightArriveAtOSRExitFromCallOperation());
+ RELEASE_ASSERT(m_state.jitCode->osrExit[osrExitIndex].willArriveAtOSRExitFromCallOperation());
OSRExitCompilationInfo& info = m_state.finalizer->osrExit[osrExitIndex];
- RELEASE_ASSERT(info.m_callOperationExceptionOSRExitEntrance.isSet());
- return m_state.finalizer->exitThunksLinkBuffer->locationOf(info.m_callOperationExceptionOSRExitEntrance);
+ RELEASE_ASSERT(info.m_thunkLabel.isSet());
+ return m_state.finalizer->exitThunksLinkBuffer->locationOf(info.m_thunkLabel);
#endif // FTL_USES_B3
}
@@ -82,28 +89,19 @@
#endif // FTL_USES_B3
}
-OSRExit* ExceptionHandlerManager::getByIdOSRExit(uint32_t stackmapRecordIndex)
+OSRExit* ExceptionHandlerManager::callOperationOSRExit(uint32_t stackmapRecordIndex)
{
- auto findResult = m_map.find(stackmapRecordIndex);
- if (findResult == m_map.end())
+ auto findResult = m_callOperationMap.find(stackmapRecordIndex);
+ if (findResult == m_callOperationMap.end())
return nullptr;
size_t osrExitIndex = findResult->value;
OSRExit* exit = &m_state.jitCode->osrExit[osrExitIndex];
- RELEASE_ASSERT(exit->m_descriptor.m_exceptionType == ExceptionType::GetById);
+ // We may have more than one exit for the same stackmap record index (i.e, for GetByIds and PutByIds).
+ // Therefore we need to make sure this exit really is a callOperation OSR exit.
+ RELEASE_ASSERT(exit->willArriveAtOSRExitFromCallOperation());
return exit;
}
-OSRExit* ExceptionHandlerManager::subOSRExit(uint32_t stackmapRecordIndex)
-{
- auto findResult = m_map.find(stackmapRecordIndex);
- if (findResult == m_map.end())
- return nullptr;
- size_t osrExitIndex = findResult->value;
- OSRExit* exit = &m_state.jitCode->osrExit[osrExitIndex];
- RELEASE_ASSERT(exit->m_descriptor.m_exceptionType == ExceptionType::SubGenerator);
- return exit;
-}
-
OSRExit* ExceptionHandlerManager::getCallOSRExitCommon(uint32_t stackmapRecordIndex)
{
auto findResult = m_map.find(stackmapRecordIndex);
Modified: trunk/Source/_javascript_Core/ftl/FTLExceptionHandlerManager.h (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLExceptionHandlerManager.h 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLExceptionHandlerManager.h 2015-12-01 00:55:32 UTC (rev 192845)
@@ -54,14 +54,14 @@
ExceptionHandlerManager(State& state);
void addNewExit(uint32_t stackmapRecordIndex, size_t osrExitIndex);
+ void addNewCallOperationExit(uint32_t stackmapRecordIndex, size_t osrExitIndex);
// These functions only make sense to be called after we've generated the OSR
// exit thunks and allocated the OSR exit thunks' link buffer.
CodeLocationLabel callOperationExceptionTarget(uint32_t stackmapRecordIndex);
CodeLocationLabel lazySlowPathExceptionTarget(uint32_t stackmapRecordIndex);
- OSRExit* getByIdOSRExit(uint32_t stackmapRecordIndex);
- OSRExit* subOSRExit(uint32_t stackmapRecordIndex);
+ OSRExit* callOperationOSRExit(uint32_t stackmapRecordIndex);
OSRExit* getCallOSRExit(uint32_t stackmapRecordIndex, const JSCall&);
OSRExit* getCallOSRExit(uint32_t stackmapRecordIndex, const JSTailCall&);
OSRExit* getCallOSRExit(uint32_t stackmapRecordIndex, const JSCallVarargs&);
@@ -78,6 +78,7 @@
State& m_state;
typedef HashMap<uint32_t, size_t, WTF::IntHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> RecordIndexToOSRExitIndexMap;
RecordIndexToOSRExitIndexMap m_map;
+ RecordIndexToOSRExitIndexMap m_callOperationMap;
};
} } // namespace JSC::FTL
Modified: trunk/Source/_javascript_Core/ftl/FTLExitThunkGenerator.cpp (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLExitThunkGenerator.cpp 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLExitThunkGenerator.cpp 2015-12-01 00:55:32 UTC (rev 192845)
@@ -53,27 +53,18 @@
info.m_thunkLabel = label();
- Jump jumpToPushIndexFromGenericUnwind;
- if (exit.m_descriptor.mightArriveAtOSRExitFromGenericUnwind()) {
+ ASSERT(!(exit.willArriveAtOSRExitFromGenericUnwind() && exit.willArriveAtOSRExitFromCallOperation()));
+ if (exit.willArriveAtOSRExitFromGenericUnwind()) {
restoreCalleeSavesFromVMCalleeSavesBuffer();
loadPtr(vm()->addressOfCallFrameForCatch(), framePointerRegister);
addPtr(TrustedImm32(- static_cast<int64_t>(m_state.jitCode->stackmaps.stackSizeForLocals())),
framePointerRegister, stackPointerRegister);
- if (exit.m_descriptor.needsRegisterRecoveryOnGenericUnwindOSRExitPath())
+ if (exit.needsRegisterRecoveryOnGenericUnwindOSRExitPath())
exit.recoverRegistersFromSpillSlot(*this, osrExitFromGenericUnwindStackSpillSlot);
-
- jumpToPushIndexFromGenericUnwind = jump();
- }
-
- if (exit.m_descriptor.mightArriveAtOSRExitFromCallOperation()) {
- info.m_callOperationExceptionOSRExitEntrance = label();
+ } else if (exit.willArriveAtOSRExitFromCallOperation())
exit.recoverRegistersFromSpillSlot(*this, osrExitFromGenericUnwindStackSpillSlot);
- }
- if (exit.m_descriptor.mightArriveAtOSRExitFromGenericUnwind())
- jumpToPushIndexFromGenericUnwind.link(this);
-
pushToSaveImmediateWithoutTouchingRegisters(TrustedImm32(index));
info.m_thunkJump = patchableJump();
Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp 2015-12-01 00:55:32 UTC (rev 192845)
@@ -56,62 +56,6 @@
{
}
-bool OSRExitDescriptor::willArriveAtExitFromIndirectExceptionCheck() const
-{
- switch (m_exceptionType) {
- case ExceptionType::JSCall:
- case ExceptionType::GetById:
- case ExceptionType::PutById:
- case ExceptionType::LazySlowPath:
- case ExceptionType::SubGenerator:
- return true;
- default:
- return false;
- }
- RELEASE_ASSERT_NOT_REACHED();
-}
-
-bool OSRExitDescriptor::mightArriveAtOSRExitFromGenericUnwind() const
-{
- switch (m_exceptionType) {
- case ExceptionType::JSCall:
- case ExceptionType::GetById:
- case ExceptionType::PutById:
- return true;
- default:
- return false;
- }
- RELEASE_ASSERT_NOT_REACHED();
-}
-
-bool OSRExitDescriptor::mightArriveAtOSRExitFromCallOperation() const
-{
- switch (m_exceptionType) {
- case ExceptionType::GetById:
- case ExceptionType::PutById:
- case ExceptionType::SubGenerator:
- return true;
- default:
- return false;
- }
- RELEASE_ASSERT_NOT_REACHED();
-}
-
-bool OSRExitDescriptor::needsRegisterRecoveryOnGenericUnwindOSRExitPath() const
-{
- // Calls/PutByIds/GetByIds all have a generic unwind osr exit paths.
- // But, GetById and PutById ICs will do register recovery themselves
- // because they're responsible for spilling necessary registers, so
- // they also must recover registers themselves.
- // Calls don't work this way. We compile Calls as patchpoints in LLVM.
- // A call patchpoint might pass us volatile registers for locations
- // we will do value recovery on. Therefore, before we make the call,
- // we must spill these registers. Otherwise, the call will clobber them.
- // Therefore, the corresponding OSR exit for the call will need to
- // recover the spilled registers.
- return m_exceptionType == ExceptionType::JSCall;
-}
-
bool OSRExitDescriptor::isExceptionHandler() const
{
return m_exceptionType != ExceptionType::None;
@@ -131,6 +75,7 @@
: OSRExitBase(descriptor.m_kind, descriptor.m_codeOrigin, descriptor.m_codeOriginForExitProfile)
, m_descriptor(descriptor)
, m_stackmapRecordIndex(stackmapRecordIndex)
+ , m_exceptionType(descriptor.m_exceptionType)
{
m_isExceptionHandler = descriptor.isExceptionHandler();
}
@@ -186,7 +131,7 @@
void OSRExit::spillRegistersToSpillSlot(CCallHelpers& jit, int32_t stackSpillSlot)
{
- RELEASE_ASSERT(m_descriptor.mightArriveAtOSRExitFromGenericUnwind() || m_descriptor.mightArriveAtOSRExitFromCallOperation());
+ RELEASE_ASSERT(willArriveAtOSRExitFromGenericUnwind() || willArriveAtOSRExitFromCallOperation());
unsigned count = 0;
for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
if (registersToPreserveForCallThatMightThrow.get(reg)) {
@@ -204,7 +149,7 @@
void OSRExit::recoverRegistersFromSpillSlot(CCallHelpers& jit, int32_t stackSpillSlot)
{
- RELEASE_ASSERT(m_descriptor.mightArriveAtOSRExitFromGenericUnwind() || m_descriptor.mightArriveAtOSRExitFromCallOperation());
+ RELEASE_ASSERT(willArriveAtOSRExitFromGenericUnwind() || willArriveAtOSRExitFromCallOperation());
unsigned count = 0;
for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
if (registersToPreserveForCallThatMightThrow.get(reg)) {
@@ -220,6 +165,64 @@
}
}
+bool OSRExit::willArriveAtExitFromIndirectExceptionCheck() const
+{
+ switch (m_exceptionType) {
+ case ExceptionType::JSCall:
+ case ExceptionType::GetById:
+ case ExceptionType::PutById:
+ case ExceptionType::LazySlowPath:
+ case ExceptionType::SubGenerator:
+ case ExceptionType::GetByIdCallOperation:
+ case ExceptionType::PutByIdCallOperation:
+ return true;
+ default:
+ return false;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+bool OSRExit::willArriveAtOSRExitFromGenericUnwind() const
+{
+ switch (m_exceptionType) {
+ case ExceptionType::JSCall:
+ case ExceptionType::GetById:
+ case ExceptionType::PutById:
+ return true;
+ default:
+ return false;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+bool OSRExit::willArriveAtOSRExitFromCallOperation() const
+{
+ switch (m_exceptionType) {
+ case ExceptionType::GetByIdCallOperation:
+ case ExceptionType::PutByIdCallOperation:
+ case ExceptionType::SubGenerator:
+ return true;
+ default:
+ return false;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+bool OSRExit::needsRegisterRecoveryOnGenericUnwindOSRExitPath() const
+{
+ // Calls/PutByIds/GetByIds all have a generic unwind osr exit paths.
+ // But, GetById and PutById ICs will do register recovery themselves
+ // because they're responsible for spilling necessary registers, so
+ // they also must recover registers themselves.
+ // Calls don't work this way. We compile Calls as patchpoints in LLVM.
+ // A call patchpoint might pass us volatile registers for locations
+ // we will do value recovery on. Therefore, before we make the call,
+ // we must spill these registers. Otherwise, the call will clobber them.
+ // Therefore, the corresponding OSR exit for the call will need to
+ // recover the spilled registers.
+ return m_exceptionType == ExceptionType::JSCall;
+}
+
} } // namespace JSC::FTL
#endif // ENABLE(FTL_JIT)
Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExit.h (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLOSRExit.h 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExit.h 2015-12-01 00:55:32 UTC (rev 192845)
@@ -136,14 +136,16 @@
// intrinsics (or meta-data, or something) to inform the backend that it's safe to
// make the predicate passed to 'exitIf()' more truthy.
-enum class ExceptionType {
+enum class ExceptionType : uint8_t {
None,
CCallException,
JSCall,
GetById,
+ GetByIdCallOperation,
PutById,
+ PutByIdCallOperation,
LazySlowPath,
- SubGenerator
+ SubGenerator,
};
struct OSRExitDescriptor {
@@ -152,10 +154,6 @@
CodeOrigin, CodeOrigin originForProfile,
unsigned numberOfArguments, unsigned numberOfLocals);
- bool willArriveAtExitFromIndirectExceptionCheck() const;
- bool mightArriveAtOSRExitFromGenericUnwind() const;
- bool mightArriveAtOSRExitFromCallOperation() const;
- bool needsRegisterRecoveryOnGenericUnwindOSRExitPath() const;
bool isExceptionHandler() const;
ExitKind m_kind;
@@ -191,6 +189,7 @@
unsigned m_patchableCodeOffset;
// Offset within Stackmap::records
uint32_t m_stackmapRecordIndex;
+ ExceptionType m_exceptionType;
RegisterSet registersToPreserveForCallThatMightThrow;
@@ -203,6 +202,11 @@
void gatherRegistersToSpillForCallIfException(StackMaps&, StackMaps::Record&);
void spillRegistersToSpillSlot(CCallHelpers&, int32_t stackSpillSlot);
void recoverRegistersFromSpillSlot(CCallHelpers& jit, int32_t stackSpillSlot);
+
+ bool willArriveAtOSRExitFromGenericUnwind() const;
+ bool willArriveAtExitFromIndirectExceptionCheck() const;
+ bool willArriveAtOSRExitFromCallOperation() const;
+ bool needsRegisterRecoveryOnGenericUnwindOSRExitPath() const;
};
} } // namespace JSC::FTL
Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompilationInfo.h (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompilationInfo.h 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompilationInfo.h 2015-12-01 00:55:32 UTC (rev 192845)
@@ -39,7 +39,6 @@
}
MacroAssembler::Label m_thunkLabel;
- MacroAssembler::Label m_callOperationExceptionOSRExitEntrance;
MacroAssembler::PatchableJump m_thunkJump;
CodeLocationLabel m_thunkAddress;
};
Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (192844 => 192845)
--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp 2015-12-01 00:33:47 UTC (rev 192844)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp 2015-12-01 00:55:32 UTC (rev 192845)
@@ -547,7 +547,7 @@
dataLog(" Exit stackmap ID: ", exit.m_descriptor.m_stackmapID, "\n");
dataLog(" Current call site index: ", exec->callSiteIndex().bits(), "\n");
dataLog(" Exit is exception handler: ", exit.m_isExceptionHandler,
- " might arrive at exit from genericUnwind(): ", exit.m_descriptor.mightArriveAtOSRExitFromGenericUnwind(),
+ " will arrive at exit from genericUnwind(): ", exit.willArriveAtOSRExitFromGenericUnwind(),
" will arrive at exit from lazy slow path: ", exit.m_descriptor.m_exceptionType == ExceptionType::LazySlowPath, "\n");
dataLog(" Exit values: ", exit.m_descriptor.m_values, "\n");
if (!exit.m_descriptor.m_materializations.isEmpty()) {