Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (213294 => 213295)
--- trunk/Source/_javascript_Core/ChangeLog 2017-03-02 20:19:35 UTC (rev 213294)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-03-02 20:35:37 UTC (rev 213295)
@@ -1,3 +1,34 @@
+2017-03-02 Mark Lam <mark....@apple.com>
+
+ Add support for selective handling of VM traps.
+ https://bugs.webkit.org/show_bug.cgi?id=169087
+
+ Reviewed by Keith Miller.
+
+ This is needed because there are some places in the VM where it's appropriate to
+ handle some types of VM traps but not others.
+
+ We implement this selection by using a VMTraps::Mask that allows the user to
+ specify which traps should be serviced.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::executeProgram):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::execute):
+ * runtime/VM.cpp:
+ (JSC::VM::handleTraps):
+ * runtime/VM.h:
+ * runtime/VMTraps.cpp:
+ (JSC::VMTraps::takeTrap): Deleted.
+ * runtime/VMTraps.h:
+ (JSC::VMTraps::Mask::Mask):
+ (JSC::VMTraps::Mask::allEventTypes):
+ (JSC::VMTraps::Mask::bits):
+ (JSC::VMTraps::Mask::init):
+ (JSC::VMTraps::needTrapHandling):
+ (JSC::VMTraps::hasTrapForEvent):
+
2017-03-02 Alex Christensen <achristen...@webkit.org>
Continue enabling WebRTC
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (213294 => 213295)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2017-03-02 20:19:35 UTC (rev 213294)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2017-03-02 20:35:37 UTC (rev 213295)
@@ -861,7 +861,8 @@
}
if (UNLIKELY(vm.needTrapHandling())) {
- vm.handleTraps(callFrame);
+ VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
+ vm.handleTraps(callFrame, mask);
RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
}
@@ -921,7 +922,8 @@
newCodeBlock = 0;
if (UNLIKELY(vm.needTrapHandling())) {
- vm.handleTraps(callFrame);
+ VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
+ vm.handleTraps(callFrame, mask);
RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
}
@@ -986,7 +988,8 @@
newCodeBlock = 0;
if (UNLIKELY(vm.needTrapHandling())) {
- vm.handleTraps(callFrame);
+ VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
+ vm.handleTraps(callFrame, mask);
RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
}
@@ -1050,7 +1053,8 @@
StackStats::CheckPoint stackCheckPoint;
if (UNLIKELY(vm.needTrapHandling())) {
- vm.handleTraps(closure.oldCallFrame);
+ VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
+ vm.handleTraps(closure.oldCallFrame, mask);
RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
}
@@ -1153,7 +1157,8 @@
}
if (UNLIKELY(vm.needTrapHandling())) {
- vm.handleTraps(callFrame);
+ VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
+ vm.handleTraps(callFrame, mask);
RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
}
@@ -1194,7 +1199,8 @@
}
if (UNLIKELY(vm.needTrapHandling())) {
- vm.handleTraps(callFrame);
+ VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
+ vm.handleTraps(callFrame, mask);
RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
}
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (213294 => 213295)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2017-03-02 20:19:35 UTC (rev 213294)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2017-03-02 20:35:37 UTC (rev 213295)
@@ -946,14 +946,17 @@
}
#endif
-void VM::handleTraps(ExecState* exec)
+void VM::handleTraps(ExecState* exec, VMTraps::Mask mask)
{
auto scope = DECLARE_THROW_SCOPE(*this);
- ASSERT(needTrapHandling());
- while (needTrapHandling()) {
- auto trapEventType = m_traps.takeTopPriorityTrap();
+ ASSERT(needTrapHandling(mask));
+ while (needTrapHandling(mask)) {
+ auto trapEventType = m_traps.takeTopPriorityTrap(mask);
switch (trapEventType) {
+ case VMTraps::NeedDebuggerBreak:
+ RELEASE_ASSERT_NOT_REACHED();
+
case VMTraps::NeedWatchdogCheck:
ASSERT(m_watchdog);
if (LIKELY(!m_watchdog->shouldTerminate(exec)))
Modified: trunk/Source/_javascript_Core/runtime/VM.h (213294 => 213295)
--- trunk/Source/_javascript_Core/runtime/VM.h 2017-03-02 20:19:35 UTC (rev 213294)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2017-03-02 20:35:37 UTC (rev 213295)
@@ -671,9 +671,9 @@
template<typename Func>
void logEvent(CodeBlock*, const char* summary, const Func& func);
- void handleTraps(ExecState*);
+ void handleTraps(ExecState*, VMTraps::Mask = VMTraps::Mask::allEventTypes());
- bool needTrapHandling() { return m_traps.needTrapHandling(); }
+ bool needTrapHandling(VMTraps::Mask mask = VMTraps::Mask::allEventTypes()) { return m_traps.needTrapHandling(mask); }
void* needTrapHandlingAddress() { return m_traps.needTrapHandlingAddress(); }
void notifyNeedTermination() { m_traps.fireTrap(VMTraps::NeedTermination); }
Modified: trunk/Source/_javascript_Core/runtime/VMTraps.cpp (213294 => 213295)
--- trunk/Source/_javascript_Core/runtime/VMTraps.cpp 2017-03-02 20:19:35 UTC (rev 213294)
+++ trunk/Source/_javascript_Core/runtime/VMTraps.cpp 2017-03-02 20:35:37 UTC (rev 213295)
@@ -34,22 +34,15 @@
setTrapForEvent(locker, eventType);
}
-bool VMTraps::takeTrap(VMTraps::EventType eventType)
+auto VMTraps::takeTopPriorityTrap(VMTraps::Mask mask) -> EventType
{
auto locker = holdLock(m_lock);
- if (hasTrapForEvent(locker, eventType)) {
- clearTrapForEvent(locker, eventType);
- return true;
- }
- return false;
-}
-
-auto VMTraps::takeTopPriorityTrap() -> EventType
-{
for (int i = 0; i < NumberOfEventTypes; ++i) {
EventType eventType = static_cast<EventType>(i);
- if (takeTrap(eventType))
+ if (hasTrapForEvent(locker, eventType, mask)) {
+ clearTrapForEvent(locker, eventType);
return eventType;
+ }
}
return Invalid;
}
Modified: trunk/Source/_javascript_Core/runtime/VMTraps.h (213294 => 213295)
--- trunk/Source/_javascript_Core/runtime/VMTraps.h 2017-03-02 20:19:35 UTC (rev 213294)
+++ trunk/Source/_javascript_Core/runtime/VMTraps.h 2017-03-02 20:35:37 UTC (rev 213295)
@@ -33,9 +33,11 @@
class VM;
class VMTraps {
+ typedef uint8_t BitField;
public:
enum EventType {
// Sorted in servicing priority order from highest to lowest.
+ NeedDebuggerBreak,
NeedTermination,
NeedWatchdogCheck,
NumberOfEventTypes, // This entry must be last in this list.
@@ -42,21 +44,51 @@
Invalid
};
- bool needTrapHandling() { return m_needTrapHandling; }
+ class Mask {
+ public:
+ enum AllEventTypes { AllEventTypesTag };
+ Mask(AllEventTypes)
+ : m_mask(std::numeric_limits<BitField>::max())
+ { }
+ static Mask allEventTypes() { return Mask(AllEventTypesTag); }
+
+ template<typename... Arguments>
+ Mask(Arguments... args)
+ : m_mask(0)
+ {
+ init(args...);
+ }
+
+ BitField bits() const { return m_mask; }
+
+ private:
+ template<typename... Arguments>
+ void init(EventType eventType, Arguments... args)
+ {
+ ASSERT(eventType < NumberOfEventTypes);
+ m_mask |= (1 << eventType);
+ init(args...);
+ }
+
+ void init() { }
+
+ BitField m_mask;
+ };
+
+ bool needTrapHandling(Mask mask) { return m_needTrapHandling & mask.bits(); }
void* needTrapHandlingAddress() { return &m_needTrapHandling; }
JS_EXPORT_PRIVATE void fireTrap(EventType);
- bool takeTrap(EventType);
- EventType takeTopPriorityTrap();
+ EventType takeTopPriorityTrap(Mask);
private:
VM& vm() const;
- bool hasTrapForEvent(Locker<Lock>&, EventType eventType)
+ bool hasTrapForEvent(Locker<Lock>&, EventType eventType, Mask mask)
{
ASSERT(eventType < NumberOfEventTypes);
- return (m_trapsBitField & (1 << eventType));
+ return (m_trapsBitField & mask.bits() & (1 << eventType));
}
void setTrapForEvent(Locker<Lock>&, EventType eventType)
{
@@ -71,8 +103,8 @@
Lock m_lock;
union {
- uint8_t m_needTrapHandling { false };
- uint8_t m_trapsBitField;
+ BitField m_needTrapHandling { 0 };
+ BitField m_trapsBitField;
};
friend class LLIntOffsetsExtractor;