Ignore:
Timestamp:
Mar 18, 2011, 4:07:16 PM (14 years ago)
Author:
[email protected]
Message:

2011-03-18 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.

[GTK] JSC crashes in 32bit Release bots after r80743
https://bugs.webkit.org/show_bug.cgi?id=56180


The crash was caused by referencing GC memory from a GC destructor. This
is not safe because destruction time / order is not guaranteed.

  • profiler/ProfileGenerator.cpp: (JSC::ProfileGenerator::create): (JSC::ProfileGenerator::ProfileGenerator): (JSC::ProfileGenerator::willExecute): (JSC::ProfileGenerator::didExecute):
  • profiler/ProfileGenerator.h: (JSC::ProfileGenerator::origin): Made ExecState* the first argument, to match the rest of this class and JSC.


Use a JSGlobalObject* instead of an ExecState* with an indirect reference
to a JSGlobalObject* to track our origin. This is simpler and more
efficient, and it removes the destruction order dependency that was causing
our crash.

  • profiler/Profiler.cpp: (JSC::Profiler::startProfiling): Updated for change to JSGlobalObject*. (JSC::Profiler::stopProfiling): New function for stopping all profiles for a given global object. This is more straight-forward than multiplexing through the old function.

(JSC::dispatchFunctionToProfiles): Updated for change to JSGlobalObject*.

  • profiler/Profiler.h: Ditto.
  • runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::~JSGlobalObject): Ditto.
Location:
trunk/Source/JavaScriptCore/profiler
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp

    r72351 r81525  
    4141static const char* NonJSExecution = "(idle)";
    4242
    43 PassRefPtr<ProfileGenerator> ProfileGenerator::create(const UString& title, ExecState* originatingExec, unsigned uid)
     43PassRefPtr<ProfileGenerator> ProfileGenerator::create(ExecState* exec, const UString& title, unsigned uid)
    4444{
    45     return adoptRef(new ProfileGenerator(title, originatingExec, uid));
     45    return adoptRef(new ProfileGenerator(exec, title, uid));
    4646}
    4747
    48 ProfileGenerator::ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid)
    49     : m_originatingGlobalExec(originatingExec ? originatingExec->lexicalGlobalObject()->globalExec() : 0)
    50     , m_profileGroup(originatingExec ? originatingExec->lexicalGlobalObject()->profileGroup() : 0)
     48ProfileGenerator::ProfileGenerator(ExecState* exec, const UString& title, unsigned uid)
     49    : m_origin(exec ? exec->lexicalGlobalObject() : 0)
     50    , m_profileGroup(exec ? exec->lexicalGlobalObject()->profileGroup() : 0)
    5151{
    5252    m_profile = Profile::create(title, uid);
    5353    m_currentNode = m_head = m_profile->head();
    54     if (originatingExec)
    55         addParentForConsoleStart(originatingExec);
     54    if (exec)
     55        addParentForConsoleStart(exec);
    5656}
    5757
     
    8181    }
    8282
    83     if (!m_originatingGlobalExec)
     83    if (!m_origin)
    8484        return;
    8585
     
    9696    }
    9797
    98     if (!m_originatingGlobalExec)
     98    if (!m_origin)
    9999        return;
    100100
  • trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h

    r72351 r81525  
    3535
    3636    class ExecState;
     37    class JSGlobalObject;
    3738    class Profile;
    3839    class ProfileNode;
     
    4243    class ProfileGenerator : public RefCounted<ProfileGenerator>  {
    4344    public:
    44         static PassRefPtr<ProfileGenerator> create(const UString& title, ExecState* originatingExec, unsigned uid);
     45        static PassRefPtr<ProfileGenerator> create(ExecState*, const UString& title, unsigned uid);
    4546
    4647        // Members
    4748        const UString& title() const;
    4849        PassRefPtr<Profile> profile() const { return m_profile; }
    49         ExecState* originatingGlobalExec() const { return m_originatingGlobalExec; }
     50        JSGlobalObject* origin() const { return m_origin; }
    5051        unsigned profileGroup() const { return m_profileGroup; }
    5152
     
    6263
    6364    private:
    64         ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid);
     65        ProfileGenerator(ExecState*, const UString& title, unsigned uid);
    6566        void addParentForConsoleStart(ExecState*);
    6667
     
    6970
    7071        RefPtr<Profile> m_profile;
    71         ExecState* m_originatingGlobalExec;
     72        JSGlobalObject* m_origin;
    7273        unsigned m_profileGroup;
    7374        RefPtr<ProfileNode> m_head;
  • trunk/Source/JavaScriptCore/profiler/Profiler.cpp

    r79132 r81525  
    6767    // Check if we currently have a Profile for this global ExecState and title.
    6868    // If so return early and don't create a new Profile.
    69     ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0;
     69    JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
    7070
    7171    for (size_t i = 0; i < m_currentProfiles.size(); ++i) {
    7272        ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
    73         if (profileGenerator->originatingGlobalExec() == globalExec && profileGenerator->title() == title)
     73        if (profileGenerator->origin() == origin && profileGenerator->title() == title)
    7474            return;
    7575    }
    7676
    7777    s_sharedEnabledProfilerReference = this;
    78     RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(title, exec, ++ProfilesUID);
     78    RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
    7979    m_currentProfiles.append(profileGenerator);
    8080}
     
    8282PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const UString& title)
    8383{
    84     ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0;
     84    JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
    8585    for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
    8686        ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
    87         if (profileGenerator->originatingGlobalExec() == globalExec && (title.isNull() || profileGenerator->title() == title)) {
     87        if (profileGenerator->origin() == origin && (title.isNull() || profileGenerator->title() == title)) {
    8888            profileGenerator->stopProfiling();
    8989            RefPtr<Profile> returnProfile = profileGenerator->profile();
     
    100100}
    101101
     102void Profiler::stopProfiling(JSGlobalObject* origin)
     103{
     104    for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
     105        ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
     106        if (profileGenerator->origin() == origin) {
     107            profileGenerator->stopProfiling();
     108            m_currentProfiles.remove(i);
     109            if (!m_currentProfiles.size())
     110                s_sharedEnabledProfilerReference = 0;
     111        }
     112    }
     113}
     114
    102115static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFrame, const Vector<RefPtr<ProfileGenerator> >& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup)
    103116{
    104117    for (size_t i = 0; i < profiles.size(); ++i) {
    105         if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->originatingGlobalExec())
     118        if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->origin())
    106119            (profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier);
    107120    }
  • trunk/Source/JavaScriptCore/profiler/Profiler.h

    r76248 r81525  
    3939    class ExecState;
    4040    class JSGlobalData;
     41    class JSGlobalObject;
    4142    class JSObject;
    4243    class JSValue;
     
    5859        void startProfiling(ExecState*, const UString& title);
    5960        PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title);
     61        void stopProfiling(JSGlobalObject*);
    6062
    6163        void willExecute(ExecState* callerCallFrame, JSValue function);
Note: See TracChangeset for help on using the changeset viewer.