Changeset 213295 in webkit


Ignore:
Timestamp:
Mar 2, 2017 12:35:37 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

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):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r213294 r213295  
     12017-03-02  Mark Lam  <mark.lam@apple.com>
     2
     3        Add support for selective handling of VM traps.
     4        https://bugs.webkit.org/show_bug.cgi?id=169087
     5
     6        Reviewed by Keith Miller.
     7
     8        This is needed because there are some places in the VM where it's appropriate to
     9        handle some types of VM traps but not others.
     10
     11        We implement this selection by using a VMTraps::Mask that allows the user to
     12        specify which traps should be serviced.
     13
     14        * interpreter/Interpreter.cpp:
     15        (JSC::Interpreter::executeProgram):
     16        (JSC::Interpreter::executeCall):
     17        (JSC::Interpreter::executeConstruct):
     18        (JSC::Interpreter::execute):
     19        * runtime/VM.cpp:
     20        (JSC::VM::handleTraps):
     21        * runtime/VM.h:
     22        * runtime/VMTraps.cpp:
     23        (JSC::VMTraps::takeTrap): Deleted.
     24        * runtime/VMTraps.h:
     25        (JSC::VMTraps::Mask::Mask):
     26        (JSC::VMTraps::Mask::allEventTypes):
     27        (JSC::VMTraps::Mask::bits):
     28        (JSC::VMTraps::Mask::init):
     29        (JSC::VMTraps::needTrapHandling):
     30        (JSC::VMTraps::hasTrapForEvent):
     31
    1322017-03-02  Alex Christensen  <achristensen@webkit.org>
    233
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r213107 r213295  
    862862
    863863    if (UNLIKELY(vm.needTrapHandling())) {
    864         vm.handleTraps(callFrame);
     864        VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     865        vm.handleTraps(callFrame, mask);
    865866        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
    866867    }
     
    922923
    923924    if (UNLIKELY(vm.needTrapHandling())) {
    924         vm.handleTraps(callFrame);
     925        VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     926        vm.handleTraps(callFrame, mask);
    925927        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
    926928    }
     
    987989
    988990    if (UNLIKELY(vm.needTrapHandling())) {
    989         vm.handleTraps(callFrame);
     991        VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     992        vm.handleTraps(callFrame, mask);
    990993        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
    991994    }
     
    10511054
    10521055    if (UNLIKELY(vm.needTrapHandling())) {
    1053         vm.handleTraps(closure.oldCallFrame);
     1056        VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     1057        vm.handleTraps(closure.oldCallFrame, mask);
    10541058        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
    10551059    }
     
    11541158
    11551159    if (UNLIKELY(vm.needTrapHandling())) {
    1156         vm.handleTraps(callFrame);
     1160        VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     1161        vm.handleTraps(callFrame, mask);
    11571162        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
    11581163    }
     
    11951200
    11961201    if (UNLIKELY(vm.needTrapHandling())) {
    1197         vm.handleTraps(callFrame);
     1202        VMTraps::Mask mask(VMTraps::NeedTermination, VMTraps::NeedWatchdogCheck);
     1203        vm.handleTraps(callFrame, mask);
    11981204        RETURN_IF_EXCEPTION(throwScope, throwScope.exception());
    11991205    }
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r213238 r213295  
    947947#endif
    948948
    949 void VM::handleTraps(ExecState* exec)
     949void VM::handleTraps(ExecState* exec, VMTraps::Mask mask)
    950950{
    951951    auto scope = DECLARE_THROW_SCOPE(*this);
    952952
    953     ASSERT(needTrapHandling());
    954     while (needTrapHandling()) {
    955         auto trapEventType = m_traps.takeTopPriorityTrap();
     953    ASSERT(needTrapHandling(mask));
     954    while (needTrapHandling(mask)) {
     955        auto trapEventType = m_traps.takeTopPriorityTrap(mask);
    956956        switch (trapEventType) {
     957        case VMTraps::NeedDebuggerBreak:
     958            RELEASE_ASSERT_NOT_REACHED();
     959
    957960        case VMTraps::NeedWatchdogCheck:
    958961            ASSERT(m_watchdog);
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r213238 r213295  
    672672    void logEvent(CodeBlock*, const char* summary, const Func& func);
    673673
    674     void handleTraps(ExecState*);
    675 
    676     bool needTrapHandling() { return m_traps.needTrapHandling(); }
     674    void handleTraps(ExecState*, VMTraps::Mask = VMTraps::Mask::allEventTypes());
     675
     676    bool needTrapHandling(VMTraps::Mask mask = VMTraps::Mask::allEventTypes()) { return m_traps.needTrapHandling(mask); }
    677677    void* needTrapHandlingAddress() { return m_traps.needTrapHandlingAddress(); }
    678678
  • trunk/Source/JavaScriptCore/runtime/VMTraps.cpp

    r213107 r213295  
    3535}
    3636
    37 bool VMTraps::takeTrap(VMTraps::EventType eventType)
     37auto VMTraps::takeTopPriorityTrap(VMTraps::Mask mask) -> EventType
    3838{
    3939    auto locker = holdLock(m_lock);
    40     if (hasTrapForEvent(locker, eventType)) {
    41         clearTrapForEvent(locker, eventType);
    42         return true;
    43     }
    44     return false;
    45 }
    46 
    47 auto VMTraps::takeTopPriorityTrap() -> EventType
    48 {
    4940    for (int i = 0; i < NumberOfEventTypes; ++i) {
    5041        EventType eventType = static_cast<EventType>(i);
    51         if (takeTrap(eventType))
     42        if (hasTrapForEvent(locker, eventType, mask)) {
     43            clearTrapForEvent(locker, eventType);
    5244            return eventType;
     45        }
    5346    }
    5447    return Invalid;
  • trunk/Source/JavaScriptCore/runtime/VMTraps.h

    r213107 r213295  
    3434
    3535class VMTraps {
     36    typedef uint8_t BitField;
    3637public:
    3738    enum EventType {
    3839        // Sorted in servicing priority order from highest to lowest.
     40        NeedDebuggerBreak,
    3941        NeedTermination,
    4042        NeedWatchdogCheck,
     
    4345    };
    4446
    45     bool needTrapHandling() { return m_needTrapHandling; }
     47    class Mask {
     48    public:
     49        enum AllEventTypes { AllEventTypesTag };
     50        Mask(AllEventTypes)
     51            : m_mask(std::numeric_limits<BitField>::max())
     52        { }
     53        static Mask allEventTypes() { return Mask(AllEventTypesTag); }
     54
     55        template<typename... Arguments>
     56        Mask(Arguments... args)
     57            : m_mask(0)
     58        {
     59            init(args...);
     60        }
     61
     62        BitField bits() const { return m_mask; }
     63
     64    private:
     65        template<typename... Arguments>
     66        void init(EventType eventType, Arguments... args)
     67        {
     68            ASSERT(eventType < NumberOfEventTypes);
     69            m_mask |= (1 << eventType);
     70            init(args...);
     71        }
     72
     73        void init() { }
     74
     75        BitField m_mask;
     76    };
     77
     78    bool needTrapHandling(Mask mask) { return m_needTrapHandling & mask.bits(); }
    4679    void* needTrapHandlingAddress() { return &m_needTrapHandling; }
    4780
    4881    JS_EXPORT_PRIVATE void fireTrap(EventType);
    4982
    50     bool takeTrap(EventType);
    51     EventType takeTopPriorityTrap();
     83    EventType takeTopPriorityTrap(Mask);
    5284
    5385private:
    5486    VM& vm() const;
    5587
    56     bool hasTrapForEvent(Locker<Lock>&, EventType eventType)
     88    bool hasTrapForEvent(Locker<Lock>&, EventType eventType, Mask mask)
    5789    {
    5890        ASSERT(eventType < NumberOfEventTypes);
    59         return (m_trapsBitField & (1 << eventType));
     91        return (m_trapsBitField & mask.bits() & (1 << eventType));
    6092    }
    6193    void setTrapForEvent(Locker<Lock>&, EventType eventType)
     
    72104    Lock m_lock;
    73105    union {
    74         uint8_t m_needTrapHandling { false };
    75         uint8_t m_trapsBitField;
     106        BitField m_needTrapHandling { 0 };
     107        BitField m_trapsBitField;
    76108    };
    77109
Note: See TracChangeset for help on using the changeset viewer.