JSGlobalData.cpp 18.5 KB
Newer Older
ap@webkit.org's avatar
ap@webkit.org committed
1
/*
2
 * Copyright (C) 2008, 2011 Apple Inc. All rights reserved.
ap@webkit.org's avatar
ap@webkit.org committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "JSGlobalData.h"

weinig@apple.com's avatar
weinig@apple.com committed
32
#include "ArgList.h"
ap@webkit.org's avatar
ap@webkit.org committed
33
#include "CommonIdentifiers.h"
34
#include "DebuggerActivation.h"
ggaren@apple.com's avatar
ggaren@apple.com committed
35
#include "FunctionConstructor.h"
36
#include "GCActivityCallback.h"
37
#include "GetterSetter.h"
38
#include "Heap.h"
39
#include "HostCallReturnValue.h"
40
#include "IncrementalSweeper.h"
41
#include "Interpreter.h"
mjs@apple.com's avatar
mjs@apple.com committed
42
#include "JSActivation.h"
43
#include "JSAPIValueWrapper.h"
44
#include "JSArray.h"
ap@webkit.org's avatar
ap@webkit.org committed
45
#include "JSClassRef.h"
46
#include "JSFunction.h"
ap@webkit.org's avatar
ap@webkit.org committed
47
#include "JSLock.h"
48
#include "JSNameScope.h"
darin@apple.com's avatar
darin@apple.com committed
49
#include "JSNotAnObject.h"
50
#include "JSPropertyNameIterator.h"
51
#include "JSWithScope.h"
52
#include "Lexer.h"
53
#include "Lookup.h"
54
#include "Nodes.h"
55
#include "ParserArena.h"
56 57 58
#include "RegExpCache.h"
#include "RegExpObject.h"
#include "StrictEvalActivation.h"
59
#include "StrongInlines.h"
60
#include <wtf/RetainPtr.h>
ap@webkit.org's avatar
ap@webkit.org committed
61
#include <wtf/Threading.h>
62
#include <wtf/WTFThreadData.h>
63

64 65 66 67
#if ENABLE(DFG_JIT)
#include "ConservativeRoots.h"
#endif

68 69 70 71
#if ENABLE(REGEXP_TRACING)
#include "RegExp.h"
#endif

72
#if USE(CF)
73
#include <CoreFoundation/CoreFoundation.h>
74 75
#endif

ap@webkit.org's avatar
ap@webkit.org committed
76 77
using namespace WTF;

78
namespace JSC {
ap@webkit.org's avatar
ap@webkit.org committed
79

80 81 82 83 84 85 86 87 88 89 90
extern const HashTable arrayConstructorTable;
extern const HashTable arrayPrototypeTable;
extern const HashTable booleanPrototypeTable;
extern const HashTable jsonTable;
extern const HashTable dateTable;
extern const HashTable dateConstructorTable;
extern const HashTable errorPrototypeTable;
extern const HashTable globalObjectTable;
extern const HashTable mathTable;
extern const HashTable numberConstructorTable;
extern const HashTable numberPrototypeTable;
91
JS_EXPORTDATA extern const HashTable objectConstructorTable;
92
extern const HashTable objectPrototypeTable;
93
extern const HashTable privateNamePrototypeTable;
94 95 96 97 98
extern const HashTable regExpTable;
extern const HashTable regExpConstructorTable;
extern const HashTable regExpPrototypeTable;
extern const HashTable stringTable;
extern const HashTable stringConstructorTable;
ap@webkit.org's avatar
ap@webkit.org committed
99

100 101 102 103 104
// Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either
// ENABLE(JIT) or ENABLE(YARR_JIT) or both are enabled. The code below
// just checks for ENABLE(JIT) or ENABLE(YARR_JIT) with this premise in mind.

#if ENABLE(ASSEMBLER)
105 106
static bool enableAssembler(ExecutableAllocator& executableAllocator)
{
107
    if (!executableAllocator.isValid() || (!Options::useJIT() && !Options::useRegExpJIT()))
108 109 110
        return false;

#if USE(CF)
111 112 113 114 115 116 117 118 119
#if COMPILER(GCC) && !COMPILER(CLANG)
    // FIXME: remove this once the EWS have been upgraded to LLVM.
    // Work around a bug of GCC with strict-aliasing.
    RetainPtr<CFStringRef> canUseJITKeyRetain(AdoptCF, CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman));
    CFStringRef canUseJITKey = canUseJITKeyRetain.get();
#else
    CFStringRef canUseJITKey = CFSTR("JavaScriptCoreUseJIT");
#endif // COMPILER(GCC) && !COMPILER(CLANG)
    RetainPtr<CFBooleanRef> canUseJIT(AdoptCF, (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication));
120
    if (canUseJIT)
121
        return kCFBooleanTrue == canUseJIT.get();
122 123 124 125 126 127 128 129 130
#endif

#if USE(CF) || OS(UNIX)
    char* canUseJITString = getenv("JavaScriptCoreUseJIT");
    return !canUseJITString || atoi(canUseJITString);
#else
    return true;
#endif
}
131
#endif // ENABLE(!ASSEMBLER)
132

133
JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
134 135 136 137 138
    :
#if ENABLE(ASSEMBLER)
      executableAllocator(*this),
#endif
      heap(this, heapType)
139
    , globalDataType(globalDataType)
ggaren@apple.com's avatar
ggaren@apple.com committed
140
    , clientData(0)
141
    , topCallFrame(CallFrame::noCaller())
142 143 144
    , arrayConstructorTable(fastNew<HashTable>(JSC::arrayConstructorTable))
    , arrayPrototypeTable(fastNew<HashTable>(JSC::arrayPrototypeTable))
    , booleanPrototypeTable(fastNew<HashTable>(JSC::booleanPrototypeTable))
145
    , dateTable(fastNew<HashTable>(JSC::dateTable))
146 147 148
    , dateConstructorTable(fastNew<HashTable>(JSC::dateConstructorTable))
    , errorPrototypeTable(fastNew<HashTable>(JSC::errorPrototypeTable))
    , globalObjectTable(fastNew<HashTable>(JSC::globalObjectTable))
149
    , jsonTable(fastNew<HashTable>(JSC::jsonTable))
150
    , mathTable(fastNew<HashTable>(JSC::mathTable))
151 152
    , numberConstructorTable(fastNew<HashTable>(JSC::numberConstructorTable))
    , numberPrototypeTable(fastNew<HashTable>(JSC::numberPrototypeTable))
153
    , objectConstructorTable(fastNew<HashTable>(JSC::objectConstructorTable))
154
    , objectPrototypeTable(fastNew<HashTable>(JSC::objectPrototypeTable))
155
    , privateNamePrototypeTable(fastNew<HashTable>(JSC::privateNamePrototypeTable))
156 157
    , regExpTable(fastNew<HashTable>(JSC::regExpTable))
    , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
158
    , regExpPrototypeTable(fastNew<HashTable>(JSC::regExpPrototypeTable))
159
    , stringTable(fastNew<HashTable>(JSC::stringTable))
160
    , stringConstructorTable(fastNew<HashTable>(JSC::stringConstructorTable))
161
    , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
ap@webkit.org's avatar
ap@webkit.org committed
162
    , propertyNames(new CommonIdentifiers(this))
163
    , emptyList(new MarkedArgumentBuffer)
164 165
    , parserArena(adoptPtr(new ParserArena))
    , keywords(adoptPtr(new Keywords(this)))
166
    , interpreter(0)
167 168
    , jsArrayClassInfo(&JSArray::s_info)
    , jsFinalObjectClassInfo(&JSFinalObject::s_info)
169
#if ENABLE(DFG_JIT)
170
    , sizeOfLastScratchBuffer(0)
171
#endif
172
    , dynamicGlobalObject(0)
173
    , cachedUTCOffset(QNaN)
174
    , m_enabledProfiler(0)
175
    , m_regExpCache(new RegExpCache(this))
176 177 178
#if ENABLE(REGEXP_TRACING)
    , m_rtTraceList(new RTTraceList())
#endif
ap@apple.com's avatar
ap@apple.com committed
179
#ifndef NDEBUG
180
    , exclusiveThread(0)
ap@apple.com's avatar
ap@apple.com committed
181
#endif
182 183 184
#if CPU(X86) && ENABLE(JIT)
    , m_timeoutCount(512)
#endif
185
    , m_newStringsSinceLastHashConst(0)
186
#if ENABLE(ASSEMBLER)
187
    , m_canUseAssembler(enableAssembler(executableAllocator))
188 189
#endif
#if ENABLE(JIT)
190
    , m_canUseJIT(m_canUseAssembler && Options::useJIT())
191 192
#endif
#if ENABLE(YARR_JIT)
193
    , m_canUseRegExpJIT(m_canUseAssembler && Options::useRegExpJIT())
194
#endif
195
#if ENABLE(GC_VALIDATION)
196
    , m_initializingObjectClass(0)
197
#endif
198
    , m_inDefineOwnProperty(false)
ap@webkit.org's avatar
ap@webkit.org committed
199
{
200
    interpreter = new Interpreter(*this);
201

202
    // Need to be careful to keep everything consistent here
203
    JSLockHolder lock(this);
204 205
    IdentifierTable* existingEntryIdentifierTable = wtfThreadData().setCurrentIdentifierTable(identifierTable);
    structureStructure.set(*this, Structure::createStructure(*this));
206
    debuggerActivationStructure.set(*this, DebuggerActivation::createStructure(*this, 0, jsNull()));
207 208
    interruptedExecutionErrorStructure.set(*this, InterruptedExecutionError::createStructure(*this, 0, jsNull()));
    terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
209 210 211 212 213
    stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
    notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, 0, jsNull()));
    propertyNameIteratorStructure.set(*this, JSPropertyNameIterator::createStructure(*this, 0, jsNull()));
    getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull()));
    apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, 0, jsNull()));
ggaren@apple.com's avatar
ggaren@apple.com committed
214
    JSScopeStructure.set(*this, JSScope::createStructure(*this, 0, jsNull()));
215 216 217 218 219 220
    executableStructure.set(*this, ExecutableBase::createStructure(*this, 0, jsNull()));
    nativeExecutableStructure.set(*this, NativeExecutable::createStructure(*this, 0, jsNull()));
    evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull()));
    programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
    functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
    regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
221
    sharedSymbolTableStructure.set(*this, SharedSymbolTable::createStructure(*this, 0, jsNull()));
222
    structureChainStructure.set(*this, StructureChain::createStructure(*this, 0, jsNull()));
223
    sparseArrayValueMapStructure.set(*this, SparseArrayValueMap::createStructure(*this, 0, jsNull()));
224 225 226

    wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);

227
#if ENABLE(JIT)
228
    jitStubs = adoptPtr(new JITThunks(this));
229
#endif
230
    
231
    interpreter->initialize(this->canUseJIT());
232
    
233
#if ENABLE(JIT)
234
    initializeHostCallReturnValue(); // This is needed to convince the linker not to drop host call return support.
235
#endif
236

237
    heap.notifyIsSafeToCollect();
238
    
239
    LLInt::Data::performAssertions(*this);
ap@webkit.org's avatar
ap@webkit.org committed
240 241 242 243
}

JSGlobalData::~JSGlobalData()
{
244
    ASSERT(!m_apiLock.currentThreadIsHoldingLock());
245
    heap.didStartVMShutdown();
246

ggaren@apple.com's avatar
ggaren@apple.com committed
247
    delete interpreter;
ap@webkit.org's avatar
ap@webkit.org committed
248
#ifndef NDEBUG
249
    interpreter = reinterpret_cast<Interpreter*>(0xbbadbeef);
ap@webkit.org's avatar
ap@webkit.org committed
250
#endif
ap@webkit.org's avatar
ap@webkit.org committed
251

252 253 254
    arrayPrototypeTable->deleteTable();
    arrayConstructorTable->deleteTable();
    booleanPrototypeTable->deleteTable();
ap@webkit.org's avatar
ap@webkit.org committed
255
    dateTable->deleteTable();
256 257 258
    dateConstructorTable->deleteTable();
    errorPrototypeTable->deleteTable();
    globalObjectTable->deleteTable();
259
    jsonTable->deleteTable();
ap@webkit.org's avatar
ap@webkit.org committed
260
    mathTable->deleteTable();
261 262
    numberConstructorTable->deleteTable();
    numberPrototypeTable->deleteTable();
263
    objectConstructorTable->deleteTable();
264
    objectPrototypeTable->deleteTable();
265
    privateNamePrototypeTable->deleteTable();
ap@webkit.org's avatar
ap@webkit.org committed
266 267
    regExpTable->deleteTable();
    regExpConstructorTable->deleteTable();
268
    regExpPrototypeTable->deleteTable();
ap@webkit.org's avatar
ap@webkit.org committed
269
    stringTable->deleteTable();
270
    stringConstructorTable->deleteTable();
271

272 273 274
    fastDelete(const_cast<HashTable*>(arrayConstructorTable));
    fastDelete(const_cast<HashTable*>(arrayPrototypeTable));
    fastDelete(const_cast<HashTable*>(booleanPrototypeTable));
275
    fastDelete(const_cast<HashTable*>(dateTable));
276 277 278
    fastDelete(const_cast<HashTable*>(dateConstructorTable));
    fastDelete(const_cast<HashTable*>(errorPrototypeTable));
    fastDelete(const_cast<HashTable*>(globalObjectTable));
279
    fastDelete(const_cast<HashTable*>(jsonTable));
280
    fastDelete(const_cast<HashTable*>(mathTable));
281 282
    fastDelete(const_cast<HashTable*>(numberConstructorTable));
    fastDelete(const_cast<HashTable*>(numberPrototypeTable));
283
    fastDelete(const_cast<HashTable*>(objectConstructorTable));
284
    fastDelete(const_cast<HashTable*>(objectPrototypeTable));
285
    fastDelete(const_cast<HashTable*>(privateNamePrototypeTable));
286 287
    fastDelete(const_cast<HashTable*>(regExpTable));
    fastDelete(const_cast<HashTable*>(regExpConstructorTable));
288
    fastDelete(const_cast<HashTable*>(regExpPrototypeTable));
289
    fastDelete(const_cast<HashTable*>(stringTable));
290
    fastDelete(const_cast<HashTable*>(stringConstructorTable));
ap@webkit.org's avatar
ap@webkit.org committed
291

292
    opaqueJSClassData.clear();
ap@webkit.org's avatar
ap@webkit.org committed
293

ap@webkit.org's avatar
ap@webkit.org committed
294 295
    delete emptyList;

ap@webkit.org's avatar
ap@webkit.org committed
296
    delete propertyNames;
297 298
    if (globalDataType != Default)
        deleteIdentifierTable(identifierTable);
ap@webkit.org's avatar
ap@webkit.org committed
299

ap@webkit.org's avatar
ap@webkit.org committed
300
    delete clientData;
301
    delete m_regExpCache;
302 303 304
#if ENABLE(REGEXP_TRACING)
    delete m_rtTraceList;
#endif
305

306
#if ENABLE(DFG_JIT)
307 308
    for (unsigned i = 0; i < scratchBuffers.size(); ++i)
        fastFree(scratchBuffers[i]);
309
#endif
ap@webkit.org's avatar
ap@webkit.org committed
310 311
}

312
PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(HeapType heapType)
313
{
314
    return adoptRef(new JSGlobalData(APIContextGroup, heapType));
315 316
}

317
PassRefPtr<JSGlobalData> JSGlobalData::create(HeapType heapType)
318
{
319
    return adoptRef(new JSGlobalData(Default, heapType));
320 321
}

322
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(HeapType heapType)
weinig@apple.com's avatar
weinig@apple.com committed
323
{
324
    return create(heapType);
weinig@apple.com's avatar
weinig@apple.com committed
325 326
}

ap@webkit.org's avatar
ap@webkit.org committed
327 328 329 330 331 332 333
bool JSGlobalData::sharedInstanceExists()
{
    return sharedInstanceInternal();
}

JSGlobalData& JSGlobalData::sharedInstance()
{
334
    GlobalJSLock globalLock;
ap@webkit.org's avatar
ap@webkit.org committed
335
    JSGlobalData*& instance = sharedInstanceInternal();
ap@webkit.org's avatar
ap@webkit.org committed
336
    if (!instance) {
337
        instance = adoptRef(new JSGlobalData(APIShared, SmallHeap)).leakRef();
ap@webkit.org's avatar
ap@webkit.org committed
338 339
        instance->makeUsableFromMultipleThreads();
    }
ap@webkit.org's avatar
ap@webkit.org committed
340 341 342 343 344 345 346 347 348
    return *instance;
}

JSGlobalData*& JSGlobalData::sharedInstanceInternal()
{
    static JSGlobalData* sharedInstance;
    return sharedInstance;
}

349
#if ENABLE(JIT)
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
{
    switch (intrinsic) {
    case CharCodeAtIntrinsic:
        return charCodeAtThunkGenerator;
    case CharAtIntrinsic:
        return charAtThunkGenerator;
    case FromCharCodeIntrinsic:
        return fromCharCodeThunkGenerator;
    case SqrtIntrinsic:
        return sqrtThunkGenerator;
    case PowIntrinsic:
        return powThunkGenerator;
    case AbsIntrinsic:
        return absThunkGenerator;
    case FloorIntrinsic:
        return floorThunkGenerator;
    case CeilIntrinsic:
        return ceilThunkGenerator;
    case RoundIntrinsic:
        return roundThunkGenerator;
    case ExpIntrinsic:
        return expThunkGenerator;
    case LogIntrinsic:
        return logThunkGenerator;
    default:
        return 0;
    }
}

380
NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
381
{
382
    return jitStubs->hostFunctionStub(this, function, constructor);
383
}
384
NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, Intrinsic intrinsic)
385
{
386
    ASSERT(canUseJIT());
387
    return jitStubs->hostFunctionStub(this, function, intrinsic != NoIntrinsic ? thunkGeneratorForIntrinsic(intrinsic) : 0, intrinsic);
388
}
389 390

#else // !ENABLE(JIT)
391
NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
392
{
393
    return NativeExecutable::create(*this, function, constructor);
394
}
395
#endif // !ENABLE(JIT)
396

ggaren@apple.com's avatar
ggaren@apple.com committed
397 398
JSGlobalData::ClientData::~ClientData()
{
ap@webkit.org's avatar
ap@webkit.org committed
399
}
ggaren@apple.com's avatar
ggaren@apple.com committed
400

401 402
void JSGlobalData::resetDateCache()
{
403
    cachedUTCOffset = QNaN;
ggaren@apple.com's avatar
ggaren@apple.com committed
404
    dstOffsetCache.reset();
405
    cachedDateString = String();
406
    cachedDateStringValue = QNaN;
407
    dateInstanceCache.reset();
408 409
}

oliver@apple.com's avatar
oliver@apple.com committed
410 411 412 413 414 415 416 417 418 419 420 421 422
void JSGlobalData::startSampling()
{
    interpreter->startSampling();
}

void JSGlobalData::stopSampling()
{
    interpreter->stopSampling();
}

void JSGlobalData::dumpSampleData(ExecState* exec)
{
    interpreter->dumpSampleData(exec);
423 424 425
#if ENABLE(ASSEMBLER)
    ExecutableAllocator::dumpProfile();
#endif
oliver@apple.com's avatar
oliver@apple.com committed
426 427
}

428 429 430 431 432 433
struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor {
    HashSet<FunctionExecutable*> currentlyExecutingFunctions;
    void operator()(JSCell* cell)
    {
        if (!cell->inherits(&FunctionExecutable::s_info))
            return;
434
        FunctionExecutable* executable = jsCast<FunctionExecutable*>(cell);
435 436
        if (currentlyExecutingFunctions.contains(executable))
            return;
437
        executable->clearCodeIfNotCompiling();
438 439 440
    }
};

441 442
void JSGlobalData::releaseExecutableMemory()
{
443 444 445 446 447 448 449 450 451 452 453
    if (dynamicGlobalObject) {
        StackPreservingRecompiler recompiler;
        HashSet<JSCell*> roots;
        heap.getConservativeRegisterRoots(roots);
        HashSet<JSCell*>::iterator end = roots.end();
        for (HashSet<JSCell*>::iterator ptr = roots.begin(); ptr != end; ++ptr) {
            ScriptExecutable* executable = 0;
            JSCell* cell = *ptr;
            if (cell->inherits(&ScriptExecutable::s_info))
                executable = static_cast<ScriptExecutable*>(*ptr);
            else if (cell->inherits(&JSFunction::s_info)) {
454
                JSFunction* function = jsCast<JSFunction*>(*ptr);
455 456 457 458 459 460 461 462 463 464 465
                if (function->isHostFunction())
                    continue;
                executable = function->jsExecutable();
            } else
                continue;
            ASSERT(executable->inherits(&ScriptExecutable::s_info));
            executable->unlinkCalls();
            if (executable->inherits(&FunctionExecutable::s_info))
                recompiler.currentlyExecutingFunctions.add(static_cast<FunctionExecutable*>(executable));
                
        }
466
        heap.objectSpace().forEachLiveCell<StackPreservingRecompiler>(recompiler);
467
    }
468
    m_regExpCache->invalidateCode();
469
    heap.collectAllGarbage();
470 471 472 473 474 475 476
}
    
void releaseExecutableMemory(JSGlobalData& globalData)
{
    globalData.releaseExecutableMemory();
}

477 478 479 480 481 482 483 484 485 486 487 488 489
#if ENABLE(DFG_JIT)
void JSGlobalData::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
{
    for (size_t i = 0; i < scratchBuffers.size(); i++) {
        ScratchBuffer* scratchBuffer = scratchBuffers[i];
        if (scratchBuffer->activeLength()) {
            void* bufferStart = scratchBuffer->dataBuffer();
            conservativeRoots.add(bufferStart, static_cast<void*>(static_cast<char*>(bufferStart) + scratchBuffer->activeLength()));
        }
    }
}
#endif

490
#if ENABLE(REGEXP_TRACING)
491
void JSGlobalData::addRegExpToTrace(RegExp* regExp)
492 493 494 495 496 497 498 499 500 501
{
    m_rtTraceList->add(regExp);
}

void JSGlobalData::dumpRegExpTrace()
{
    // The first RegExp object is ignored.  It is create by the RegExpPrototype ctor and not used.
    RTTraceList::iterator iter = ++m_rtTraceList->begin();
    
    if (iter != m_rtTraceList->end()) {
502 503 504 505
        dataLog("\nRegExp Tracing\n");
        dataLog("                                                            match()    matches\n");
        dataLog("Regular Expression                          JIT Address      calls      found\n");
        dataLog("----------------------------------------+----------------+----------+----------\n");
506 507 508 509 510 511
    
        unsigned reCount = 0;
    
        for (; iter != m_rtTraceList->end(); ++iter, ++reCount)
            (*iter)->printTraceData();

512
        dataLog("%d Regular Expressions\n", reCount);
513 514 515 516 517 518 519 520 521 522
    }
    
    m_rtTraceList->clear();
}
#else
void JSGlobalData::dumpRegExpTrace()
{
}
#endif

ggaren@apple.com's avatar
ggaren@apple.com committed
523
} // namespace JSC