summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-06-25 13:35:59 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-06-25 13:35:59 +0200
commit79ad030d505ccf79cf10aa9f8189ca3e2f61f6f4 (patch)
tree0287b1a69d84492c901e8bc820e635e7133809a0 /Source/JavaScriptCore
parent682ab87480e7757346802ce7f54cfdbdfeb2339e (diff)
downloadqtwebkit-79ad030d505ccf79cf10aa9f8189ca3e2f61f6f4.tar.gz
Imported WebKit commit c4b613825abd39ac739a47d7b4410468fcef66dc (http://svn.webkit.org/repository/webkit/trunk@121147)
New snapshot that includes Win32 debug build fix (use SVGAllInOne)
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/API/JSBase.h2
-rw-r--r--Source/JavaScriptCore/CMakeLists.txt2
-rw-r--r--Source/JavaScriptCore/ChangeLog617
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig1
-rw-r--r--Source/JavaScriptCore/GNUmakefile.list.am4
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.pri6
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def1
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj16
-rw-r--r--Source/JavaScriptCore/Target.pri2
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h5
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h9
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h5
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp24
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h13
-rw-r--r--Source/JavaScriptCore/bytecode/GlobalResolveInfo.h9
-rw-r--r--Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp88
-rw-r--r--Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h86
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp144
-rw-r--r--Source/JavaScriptCore/dfg/DFGCapabilities.h1
-rw-r--r--Source/JavaScriptCore/dfg/DFGCommon.h5
-rw-r--r--Source/JavaScriptCore/dfg/DFGDisassembler.cpp115
-rw-r--r--Source/JavaScriptCore/dfg/DFGDisassembler.h82
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.cpp10
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.cpp99
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h24
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.cpp26
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.h46
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h5
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeFlags.cpp47
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp13
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp28
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h6
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h10
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp4
-rw-r--r--Source/JavaScriptCore/heap/HeapTimer.cpp25
-rw-r--r--Source/JavaScriptCore/heap/HeapTimer.h25
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.cpp50
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.h26
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp15
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.h4
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.cpp6
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.cpp57
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h3
-rw-r--r--Source/JavaScriptCore/jit/JIT.cpp7
-rw-r--r--Source/JavaScriptCore/jit/JIT.h2
-rw-r--r--Source/JavaScriptCore/jit/JITCall32_64.cpp4
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp7
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp86
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h3
-rw-r--r--Source/JavaScriptCore/offlineasm/offsets.rb11
-rw-r--r--Source/JavaScriptCore/runtime/JSExportMacros.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h17
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h1
-rw-r--r--Source/JavaScriptCore/runtime/Options.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Options.h3
-rw-r--r--Source/JavaScriptCore/shell/CMakeLists.txt2
-rw-r--r--Source/JavaScriptCore/wscript2
64 files changed, 1647 insertions, 302 deletions
diff --git a/Source/JavaScriptCore/API/JSBase.h b/Source/JavaScriptCore/API/JSBase.h
index f46a41755..fed54fe23 100644
--- a/Source/JavaScriptCore/API/JSBase.h
+++ b/Source/JavaScriptCore/API/JSBase.h
@@ -71,7 +71,7 @@ typedef struct OpaqueJSValue* JSObjectRef;
#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__)
#define JS_EXPORT __attribute__((visibility("default")))
#elif defined(WIN32) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__CC_ARM) || defined(__ARMCC__)
-#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore)
+#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
#define JS_EXPORT __declspec(dllexport)
#else
#define JS_EXPORT __declspec(dllimport)
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 24e67b940..06139a4d2 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -54,6 +54,7 @@ SET(JavaScriptCore_SOURCES
bytecode/PolymorphicPutByIdList.cpp
bytecode/SpeculatedType.cpp
bytecode/PutByIdStatus.cpp
+ bytecode/ResolveGlobalStatus.cpp
bytecode/SamplingTool.cpp
bytecode/StructureStubInfo.cpp
bytecode/Watchpoint.cpp
@@ -71,6 +72,7 @@ SET(JavaScriptCore_SOURCES
dfg/DFGConstantFoldingPhase.cpp
dfg/DFGCorrectableJumpPoint.cpp
dfg/DFGCSEPhase.cpp
+ dfg/DFGDisassembler.cpp
dfg/DFGDominators.cpp
dfg/DFGDriver.cpp
dfg/DFGFixupPhase.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 3907efc13..20df558bb 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,33 +1,608 @@
-2012-06-19 Joel Dillon <joel.dillon@codethink.co.uk> Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+2012-06-23 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r121058.
+ http://trac.webkit.org/changeset/121058
+ https://bugs.webkit.org/show_bug.cgi?id=89809
+
+ Patch causes plugins tests to crash in GTK debug builds
+ (Requested by zdobersek on #webkit).
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (APIEntryShimWithoutLock):
+ (JSC::APIEntryShim::APIEntryShim):
+ (APIEntryShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+ * API/JSContextRef.cpp:
+ (JSGlobalContextCreate):
+ (JSGlobalContextCreateInGroup):
+ (JSGlobalContextRelease):
+ (JSContextCreateBacktrace):
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::tryAllocateSlowCase):
+ * heap/Heap.cpp:
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::collect):
+ (JSC::Heap::setActivityCallback):
+ (JSC::Heap::activityCallback):
+ (JSC::Heap::sweeper):
+ * heap/Heap.h:
+ (Heap):
+ * heap/HeapTimer.cpp:
+ (JSC::HeapTimer::~HeapTimer):
+ (JSC::HeapTimer::invalidate):
+ (JSC::HeapTimer::timerDidFire):
+ (JSC):
+ * heap/HeapTimer.h:
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::doWork):
+ (JSC::IncrementalSweeper::create):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::allocateSlowCase):
+ * heap/WeakBlock.cpp:
+ (JSC::WeakBlock::reap):
+ * jsc.cpp:
+ (functionGC):
+ (functionReleaseExecutableMemory):
+ (jscmain):
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/GCActivityCallback.h:
+ (DefaultGCActivityCallback):
+ (JSC::DefaultGCActivityCallback::create):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ (JSC::JSGlobalData::sharedInstance):
+ (JSC::JSGlobalData::sharedInstanceInternal):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::~JSGlobalObject):
+ (JSC::JSGlobalObject::init):
+ * runtime/JSLock.cpp:
+ (JSC):
+ (JSC::createJSLockCount):
+ (JSC::JSLock::lockCount):
+ (JSC::setLockCount):
+ (JSC::JSLock::JSLock):
+ (JSC::JSLock::lock):
+ (JSC::JSLock::unlock):
+ (JSC::JSLock::currentThreadIsHoldingLock):
+ (JSC::JSLock::DropAllLocks::DropAllLocks):
+ (JSC::JSLock::DropAllLocks::~DropAllLocks):
+ * runtime/JSLock.h:
+ (JSC):
+ (JSLock):
+ (JSC::JSLock::JSLock):
+ (JSC::JSLock::~JSLock):
+ (DropAllLocks):
+ * runtime/WeakGCMap.h:
+ (JSC::WeakGCMap::set):
+ * testRegExp.cpp:
+ (realMain):
- [Qt][Win] Fix broken QtWebKit5.lib linking
- https://bugs.webkit.org/show_bug.cgi?id=88321
+2012-06-22 Alexandru Chiculita <achicu@adobe.com>
- Reviewed by NOBODY (OOPS!).
+ [CSS Shaders] Re-enable the CSS Shaders compile time flag on Safari Mac
+ https://bugs.webkit.org/show_bug.cgi?id=89781
- Also update the Wx build to use the new define.
+ Reviewed by Dean Jackson.
- * API/JSBase.h:
- * runtime/JSExportMacros.h:
- * wscript:
+ Added ENABLE_CSS_SHADERS flag as enabled by default on Safari for Mac.
+
+ * Configurations/FeatureDefines.xcconfig:
-2012-06-13 Patrick Gansterer <paroga@webkit.org>
+2012-06-22 Filip Pizlo <fpizlo@apple.com>
+
+ DFG tier-up should happen in prologues, not epilogues
+ https://bugs.webkit.org/show_bug.cgi?id=89752
+
+ Reviewed by Geoffrey Garen.
+
+ This change has two outcomes:
+
+ 1) Slightly reduces the likelihood that a function will be optimized both
+ standalone and via inlining. Previously, if you had a call sequence like foo()
+ calls bar() exactly once, and nobody else calls bar(), then bar() would get
+ optimized first (because it returns first) and then foo() gets optimized. If foo()
+ can inline bar() then that means that bar() gets optimized twice. But now, if we
+ optimize in prologues, then foo() will be optimized first. If it inlines bar(),
+ that means that there will no longer be any calls to bar().
+
+ 2) It lets us kill some code in JITStubs. Epilogue tier-up was very different from
+ loop tier-up, since epilogue tier-up should not attempt OSR. But prologue tier-up
+ requires OSR (albeit really easy OSR since it's the top of the compilation unit),
+ so it becomes just like loop tier-up. As a result, we now have one optimization
+ hook (cti_optimize) instead of two (cti_optimize_from_loop and
+ cti_optimize_from_ret).
+
+ As a consequence of not having an optimization check in epilogues, the OSR exit
+ code must now trigger reoptimization itself instead of just signaling the epilogue
+ check to fire.
+
+ This also adds the ability to count the number of DFG compilations, which was
+ useful for debugging this patch and might be useful for other things in the future.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::reoptimize):
+ (JSC):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGDriver.cpp:
+ (DFG):
+ (JSC::DFG::getNumCompilations):
+ (JSC::DFG::compile):
+ * dfg/DFGDriver.h:
+ (DFG):
+ * dfg/DFGOSRExitCompiler.cpp:
+ (JSC::DFG::OSRExitCompiler::handleExitCounts):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::emitOptimizationCheck):
+ * jit/JIT.h:
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::emit_op_ret):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_ret):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ (JSC::JIT::emit_op_enter):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_enter):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+
+2012-06-20 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ JSLock should be per-JSGlobalData
+ https://bugs.webkit.org/show_bug.cgi?id=89123
+
+ Reviewed by Gavin Barraclough.
- [WIN] Remove dependency on pthread from MachineStackMarker
- https://bugs.webkit.org/show_bug.cgi?id=68429
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * API/APIShims.h:
+ (APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to
+ determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the
+ HeapTimer class because timerDidFire could run after somebody has started to tear down that particular
+ JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after
+ its destruction has begun.
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): Now derefs if it also refed.
+ (JSC::APIEntryShim::APIEntryShim):
+ (APIEntryShim):
+ (JSC::APIEntryShim::~APIEntryShim):
+ (JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors.
+ Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock
+ and before we've released it, which can only done in APIEntryShim.
+ (JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here.
+ * API/JSContextRef.cpp:
+ (JSGlobalContextCreate):
+ (JSGlobalContextCreateInGroup):
+ (JSGlobalContextRelease):
+ (JSContextCreateBacktrace):
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::tryAllocateSlowCase):
+ * heap/Heap.cpp:
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::collect):
+ (JSC::Heap::setActivityCallback):
+ (JSC::Heap::activityCallback):
+ (JSC::Heap::sweeper):
+ * heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they
+ are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback
+ and the IncrementalSweeper to make sure they're the last things that get initialized during construction to
+ prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about.
+ (Heap):
+ * heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown.
+ (JSC::HeapTimer::~HeapTimer):
+ (JSC::HeapTimer::invalidate):
+ (JSC):
+ (JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread
+ that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the
+ HeapTimer and schedule it to fire immediately so that it can notice and kill itself.
+ (JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed
+ out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim,
+ but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case
+ we were interrupted between releasing our mutex and trying to grab the APILock.
+ * heap/HeapTimer.h:
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles
+ all of that for us.
+ (JSC::IncrementalSweeper::create):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::allocateSlowCase):
+ * heap/WeakBlock.cpp:
+ (JSC::WeakBlock::reap):
+ * jsc.cpp:
+ (functionGC):
+ (functionReleaseExecutableMemory):
+ (jscmain):
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/GCActivityCallback.h:
+ (DefaultGCActivityCallback):
+ (JSC::DefaultGCActivityCallback::create):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper)
+ that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity
+ it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the
+ APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes.
+ (JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock.
+ (JSC::JSGlobalData::sharedInstanceInternal):
+ * runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and
+ de-refing JSGlobalDatas on separate threads since we don't do it that often anyways.
+ (JSGlobalData):
+ (JSC::JSGlobalData::apiLock):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::~JSGlobalObject):
+ (JSC::JSGlobalObject::init):
+ * runtime/JSLock.cpp:
+ (JSC):
+ (JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance.
+ (JSC::GlobalJSLock::~GlobalJSLock):
+ (JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that
+ it can successfully unlock it later without it disappearing from underneath it.
+ (JSC::JSLockHolder::~JSLockHolder):
+ (JSC::JSLock::JSLock):
+ (JSC::JSLock::~JSLock):
+ (JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for
+ actually waiting for long periods.
+ (JSC::JSLock::unlock):
+ (JSC::JSLock::currentThreadIsHoldingLock):
+ (JSC::JSLock::dropAllLocks):
+ (JSC::JSLock::dropAllLocksUnconditionally):
+ (JSC::JSLock::grabAllLocks):
+ (JSC::JSLock::DropAllLocks::DropAllLocks):
+ (JSC::JSLock::DropAllLocks::~DropAllLocks):
+ * runtime/JSLock.h:
+ (JSC):
+ (GlobalJSLock):
+ (JSLockHolder):
+ (JSLock):
+ (DropAllLocks):
+ * runtime/WeakGCMap.h:
+ (JSC::WeakGCMap::set):
+ * testRegExp.cpp:
+ (realMain):
+
+2012-06-22 Peter Beverloo <peter@chromium.org>
+
+ [Chromium] Disable c++0x compatibility warnings in JavaScriptCore.gyp when building for Android
+ https://bugs.webkit.org/show_bug.cgi?id=88853
+
+ Reviewed by Steve Block.
+
+ The Android exclusions were necessary to fix a gyp generation error, as
+ the gcc_version variable wasn't being defined for Android. Remove these
+ exceptions when Chromium is able to define the gcc_version variable.
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2012-06-21 Filip Pizlo <fpizlo@apple.com>
+
+ op_resolve_global should not prevent DFG inlining
+ https://bugs.webkit.org/show_bug.cgi?id=89726
+
+ Reviewed by Gavin Barraclough.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/GlobalResolveInfo.h:
+ (JSC::GlobalResolveInfo::GlobalResolveInfo):
+ (GlobalResolveInfo):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-06-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should inline 'new Array()'
+ https://bugs.webkit.org/show_bug.cgi?id=89632
+
+ Reviewed by Geoffrey Garen.
+
+ This adds support for treating InternalFunction like intrinsics. The code
+ to do so is actually quite clean, so I don't feel bad about perpetuating
+ the InternalFunction vs. JSFunction-with-NativeExecutable dichotomy.
+
+ Currently this newfound power is only used to inline 'new Array()'.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+ (DFG):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::isInternalFunctionConstant):
+ (JSC::DFG::Graph::valueOfInternalFunctionConstant):
- Reviewed by NOBODY (OOPS!).
+2012-06-21 Mark Hahnenberg <mhahnenberg@apple.com>
- Implement pthread TLS functionality with native windows functions.
+ Adding copyrights to new files.
- * heap/MachineStackMarker.cpp: Use the new functions instead of pthread directly.
- * heap/MachineStackMarker.h:
- * wtf/ThreadSpecific.h:
- (WTF::ThreadSpecificKeyCreate): Added wrapper around pthread_key_create.
- (WTF::ThreadSpecificKeyDelete): Added wrapper around pthread_key_delete.
- (WTF::ThreadSpecificSet): Added wrapper around pthread_setspecific.
- (WTF::ThreadSpecificGet): Added wrapper around pthread_getspecific.
- * wtf/ThreadSpecificWin.cpp:
+ * heap/HeapTimer.cpp:
+ * heap/HeapTimer.h:
+ * heap/IncrementalSweeper.cpp:
+ * heap/IncrementalSweeper.h:
+
+2012-06-21 Arnaud Renevier <arno@renevier.net>
+
+ make sure headers are included only once per file
+ https://bugs.webkit.org/show_bug.cgi?id=88922
+
+ Reviewed by Alexey Proskuryakov.
+
+ * bytecode/CodeBlock.h:
+ * heap/MachineStackMarker.cpp:
+ * runtime/JSVariableObject.h:
+
+2012-06-21 Ryuan Choi <ryuan.choi@gmail.com>
+
+ [EFL][WK2] Make WebKit2/Efl headers and resources installable.
+ https://bugs.webkit.org/show_bug.cgi?id=88207
+
+ Reviewed by Chang Shu.
+
+ * shell/CMakeLists.txt: Use ${EXEC_INSTALL_DIR} instead of hardcoding "bin"
+
+2012-06-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reduced (but did not eliminate) use of "berzerker GC"
+ https://bugs.webkit.org/show_bug.cgi?id=89237
+
+ Reviewed by Gavin Barraclough.
+
+ (PART 1)
+
+ This patch turned out to be crashy, so I'm landing the non-crashy bits
+ first.
+
+ This part is pre-requisite refactoring. I didn't actually turn off
+ "berzerker GC" or turn on incremental shrinking.
+
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::removeBlock): Make sure to clear the free list when
+ we throw away the block we're currently allocating out of. Otherwise, we'll
+ allocate out of a stale free list.
+
+ * heap/MarkedSpace.cpp:
+ (JSC::Free::Free):
+ (JSC::Free::operator()):
+ (JSC::Free::returnValue): Refactored this functor to use a shared helper
+ function, so we can share our implementation with the incremental sweeper.
+
+ Also changed to freeing individual blocks immediately instead of linking
+ them into a list for later freeing. This makes the programming interface
+ simpler, and it's slightly more efficient to boot.
+
+ (JSC::MarkedSpace::~MarkedSpace): Updated for rename.
+
+ (JSC::MarkedSpace::freeBlock):
+ (JSC::MarkedSpace::freeOrShrinkBlock): New helper functions to share behavior
+ with the incremental sweeper.
+
+ (JSC::MarkedSpace::shrink): Updated for new functor behavior.
+
+ * heap/MarkedSpace.h: Statically typed languages are awesome.
+
+2012-06-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should optimize ResolveGlobal
+ https://bugs.webkit.org/show_bug.cgi?id=89617
+
+ Reviewed by Oliver Hunt.
+
+ This adds inlining of ResolveGlobal accesses that are known monomorphic. It also
+ adds the specific function optimization to ResolveGlobal, when it is inlined. And,
+ it makes internal functions act like specific functions, since that will be the
+ most common use-case of this optimization.
+
+ This is only a slighy speed-up (sub 1%), since we don't yet do the obvious thing
+ with this optimization, which is to completely inline common "globally resolved"
+ function and constructor calls, like "new Array()".
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::globalResolveInfoForBytecodeOffset):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::numberOfGlobalResolveInfos):
+ * bytecode/GlobalResolveInfo.h:
+ (JSC::getGlobalResolveInfoBytecodeOffset):
+ (JSC):
+ * bytecode/ResolveGlobalStatus.cpp: Added.
+ (JSC):
+ (JSC::computeForStructure):
+ (JSC::computeForLLInt):
+ (JSC::ResolveGlobalStatus::computeFor):
+ * bytecode/ResolveGlobalStatus.h: Added.
+ (JSC):
+ (ResolveGlobalStatus):
+ (JSC::ResolveGlobalStatus::ResolveGlobalStatus):
+ (JSC::ResolveGlobalStatus::state):
+ (JSC::ResolveGlobalStatus::isSet):
+ (JSC::ResolveGlobalStatus::operator!):
+ (JSC::ResolveGlobalStatus::isSimple):
+ (JSC::ResolveGlobalStatus::takesSlowPath):
+ (JSC::ResolveGlobalStatus::structure):
+ (JSC::ResolveGlobalStatus::offset):
+ (JSC::ResolveGlobalStatus::specificValue):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * runtime/JSObject.cpp:
+ (JSC::getCallableObjectSlow):
+ (JSC):
+ (JSC::JSObject::put):
+ (JSC::JSObject::putDirectVirtual):
+ (JSC::JSObject::putDirectAccessor):
+ * runtime/JSObject.h:
+ (JSC):
+ (JSC::getCallableObject):
+ (JSC::JSObject::putOwnDataProperty):
+ (JSC::JSObject::putDirect):
+ (JSC::JSObject::putDirectWithoutTransition):
+
+2012-06-20 Filip Pizlo <fpizlo@apple.com>
+
+ Functions on global objects should be specializable
+ https://bugs.webkit.org/show_bug.cgi?id=89615
+
+ Reviewed by Oliver Hunt.
+
+ I tested to see if this brought back the bug in https://bugs.webkit.org/show_bug.cgi?id=33343,
+ and it didn't. Bug 33343 was the reason why we disabled global object function specialization
+ to begin with. So I'm guessing this is safe.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+
+2012-06-20 Filip Pizlo <fpizlo@apple.com>
+
+ build-webkit failure due to illegal 32-bit integer constants in code
+ generated by offlineasm
+ https://bugs.webkit.org/show_bug.cgi?id=89347
+
+ Reviewed by Geoffrey Garen.
+
+ The offending constants are the magic numbers used by offlineasm to find
+ offsets in the generated machine code. Added code to turn them into what
+ the C++ compiler will believe to be valid 32-bit values.
+
+ * offlineasm/offsets.rb:
+
+2012-06-19 Geoffrey Garen <ggaren@apple.com>
+
+ Made the incremental sweeper more aggressive
+ https://bugs.webkit.org/show_bug.cgi?id=89527
+
+ Reviewed by Oliver Hunt.
+
+ This is a pre-requisite to getting rid of "berzerker GC" because we need
+ the sweeper to reclaim memory in a timely fashion, or we'll see a memory
+ footprint regression.
+
+ * heap/IncrementalSweeper.h:
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::scheduleTimer): Since the time slice is predictable,
+ no need to use a data member to record it.
+
+ (JSC::IncrementalSweeper::doSweep): Sweep as many blocks as we can in a
+ small time slice. This is better than sweeping only one block per timer
+ fire because that strategy has a heavy timer overhead, and artificially
+ delays memory reclamation.
+
+2012-06-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should be able to print disassembly interleaved with the IR
+ https://bugs.webkit.org/show_bug.cgi?id=89551
+
+ Reviewed by Geoffrey Garen.
+
+ This change also removes running Dominators unconditionally on every DFG
+ compile. Dominators are designed to be computed on-demand, and currently
+ the only demand is graph dumps.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::labelIgnoringWatchpoints):
+ (ARMv7Assembler):
+ * assembler/AbstractMacroAssembler.h:
+ (AbstractMacroAssembler):
+ (JSC::AbstractMacroAssembler::labelIgnoringWatchpoints):
+ * assembler/X86Assembler.h:
+ (X86Assembler):
+ (JSC::X86Assembler::labelIgnoringWatchpoints):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::shouldShowDisassembly):
+ (DFG):
+ * dfg/DFGDisassembler.cpp: Added.
+ (DFG):
+ (JSC::DFG::Disassembler::Disassembler):
+ (JSC::DFG::Disassembler::dump):
+ (JSC::DFG::Disassembler::dumpDisassembly):
+ * dfg/DFGDisassembler.h: Added.
+ (DFG):
+ (Disassembler):
+ (JSC::DFG::Disassembler::setStartOfCode):
+ (JSC::DFG::Disassembler::setForBlock):
+ (JSC::DFG::Disassembler::setForNode):
+ (JSC::DFG::Disassembler::setEndOfMainPath):
+ (JSC::DFG::Disassembler::setEndOfCode):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ (JSC::DFG::Graph::amountOfNodeWhiteSpace):
+ (DFG):
+ (JSC::DFG::Graph::printNodeWhiteSpace):
+ (JSC::DFG::Graph::dump):
+ (JSC::DFG::Graph::dumpBlockHeader):
+ * dfg/DFGGraph.h:
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::JITCompiler):
+ (DFG):
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ (JITCompiler):
+ (JSC::DFG::JITCompiler::setStartOfCode):
+ (JSC::DFG::JITCompiler::setForBlock):
+ (JSC::DFG::JITCompiler::setForNode):
+ (JSC::DFG::JITCompiler::setEndOfMainPath):
+ (JSC::DFG::JITCompiler::setEndOfCode):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::willHaveCodeGen):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::nodeFlagsAsString):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * runtime/Options.cpp:
+ (Options):
+ (JSC::Options::initializeOptions):
+ * runtime/Options.h:
+ (Options):
2012-06-19 Filip Pizlo <fpizlo@apple.com>
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index b96b21db3..ae2c393b1 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -40,6 +40,7 @@ ENABLE_CSP_NEXT = ;
ENABLE_CSS3_FLEXBOX = ENABLE_CSS3_FLEXBOX;
ENABLE_CSS_EXCLUSIONS = ENABLE_CSS_EXCLUSIONS;
ENABLE_CSS_FILTERS = ENABLE_CSS_FILTERS;
+ENABLE_CSS_SHADERS = ENABLE_CSS_SHADERS;
ENABLE_CSS_IMAGE_RESOLUTION = ;
ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS;
ENABLE_CSS_VARIABLES = ;
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index 77409fe93..84d6e60ff 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -126,6 +126,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/PutByIdStatus.cpp \
Source/JavaScriptCore/bytecode/PutByIdStatus.h \
Source/JavaScriptCore/bytecode/PutKind.h \
+ Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp \
+ Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h \
Source/JavaScriptCore/bytecode/SamplingTool.cpp \
Source/JavaScriptCore/bytecode/SamplingTool.h \
Source/JavaScriptCore/bytecode/StructureSet.h \
@@ -168,6 +170,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.h \
Source/JavaScriptCore/dfg/DFGCSEPhase.cpp \
Source/JavaScriptCore/dfg/DFGCSEPhase.h \
+ Source/JavaScriptCore/dfg/DFGDisassembler.cpp \
+ Source/JavaScriptCore/dfg/DFGDisassembler.h \
Source/JavaScriptCore/dfg/DFGDominators.cpp \
Source/JavaScriptCore/dfg/DFGDominators.h \
Source/JavaScriptCore/dfg/DFGDoubleFormatState.h \
diff --git a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp b/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
index 8da950f5e..c60a2e68d 100644
--- a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
+++ b/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
@@ -47,7 +47,7 @@
],
},
'conditions': [
- ['os_posix == 1 and OS != "mac" and OS != "android" and gcc_version==46', {
+ ['os_posix == 1 and OS != "mac" and gcc_version==46', {
'target_defaults': {
# Disable warnings about c++0x compatibility, as some names (such as nullptr) conflict
# with upcoming c++0x types.
diff --git a/Source/JavaScriptCore/JavaScriptCore.pri b/Source/JavaScriptCore/JavaScriptCore.pri
index f6580c51f..380bbaf1b 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pri
+++ b/Source/JavaScriptCore/JavaScriptCore.pri
@@ -34,6 +34,12 @@ INCLUDEPATH += \
win32-* {
LIBS += -lwinmm
+
+ win32-g++* {
+ LIBS += -lpthreadGC2
+ } else:win32-msvc* {
+ LIBS += -lpthreadVC2
+ }
}
wince* {
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 365038cee..c48ef49c6 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -189,6 +189,7 @@ EXPORTS
?get@Structure@JSC@@QAEIAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z
?getCalculatedDisplayName@JSC@@YA?AVUString@1@PAVExecState@1@PAVJSObject@1@@Z
?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z
+ ?getCallableObjectSlow@JSC@@YAPAVJSCell@1@PAV21@@Z
?getConstructData@JSCell@JSC@@SA?AW4ConstructType@2@PAV12@AATConstructData@2@@Z
?getCurrentLocalTime@WTF@@YAXPAUtm@@@Z
?getObject@JSCell@JSC@@QAEPAVJSObject@2@XZ
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 2ffc9e266..a64a1065f 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -209,6 +209,10 @@
0FF4274B158EBE91004CB9FF /* udis86.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4273F158EBD94004CB9FF /* udis86.h */; };
0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4274C158EBFE1004CB9FF /* udis86_itab_holder.c */; };
0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */; };
+ 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */; };
+ 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */; };
+ 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */; };
0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -929,6 +933,10 @@
0FF4273F158EBD94004CB9FF /* udis86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = udis86.h; path = disassembler/udis86/udis86.h; sourceTree = "<group>"; };
0FF4274C158EBFE1004CB9FF /* udis86_itab_holder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udis86_itab_holder.c; path = disassembler/udis86/udis86_itab_holder.c; sourceTree = "<group>"; };
0FF4275615914A20004CB9FF /* LinkBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkBuffer.cpp; sourceTree = "<group>"; };
+ 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDisassembler.cpp; path = dfg/DFGDisassembler.cpp; sourceTree = "<group>"; };
+ 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDisassembler.h; path = dfg/DFGDisassembler.h; sourceTree = "<group>"; };
+ 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResolveGlobalStatus.cpp; sourceTree = "<group>"; };
+ 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolveGlobalStatus.h; sourceTree = "<group>"; };
0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFAPhase.cpp; path = dfg/DFGCFAPhase.cpp; sourceTree = "<group>"; };
0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFAPhase.h; path = dfg/DFGCFAPhase.h; sourceTree = "<group>"; };
@@ -2201,6 +2209,8 @@
0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */,
0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */,
0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */,
+ 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */,
+ 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */,
0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */,
0FD81AD0154FB4EB00983E72 /* DFGDominators.h */,
0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */,
@@ -2341,6 +2351,8 @@
0F93329814CA7DC10085F3C6 /* MethodCallLinkStatus.h */,
0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
+ 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */,
+ 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */,
0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */,
@@ -2759,6 +2771,8 @@
0FF42748158EBE91004CB9FF /* udis86_syn.h in Headers */,
0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
0FF4274B158EBE91004CB9FF /* udis86.h in Headers */,
+ 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
+ 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3345,6 +3359,8 @@
C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */,
0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */,
C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */,
+ 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
+ 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri
index e3488c74e..2f479222a 100644
--- a/Source/JavaScriptCore/Target.pri
+++ b/Source/JavaScriptCore/Target.pri
@@ -64,6 +64,7 @@ SOURCES += \
bytecode/Opcode.cpp \
bytecode/PolymorphicPutByIdList.cpp \
bytecode/PutByIdStatus.cpp \
+ bytecode/ResolveGlobalStatus.cpp \
bytecode/SamplingTool.cpp \
bytecode/SpeculatedType.cpp \
bytecode/StructureStubInfo.cpp \
@@ -102,6 +103,7 @@ SOURCES += \
dfg/DFGConstantFoldingPhase.cpp \
dfg/DFGCorrectableJumpPoint.cpp \
dfg/DFGCSEPhase.cpp \
+ dfg/DFGDisassembler.cpp \
dfg/DFGDominators.cpp \
dfg/DFGDriver.cpp \
dfg/DFGFixupPhase.cpp \
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index 95c812c94..81977e2bd 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1827,6 +1827,11 @@ public:
m_formatter.oneWordOp8Imm8(OP_NOP_T1, 0);
}
+ AssemblerLabel labelIgnoringWatchpoints()
+ {
+ return m_formatter.label();
+ }
+
AssemblerLabel labelForWatchpoint()
{
AssemblerLabel result = m_formatter.label();
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 27b8a58d1..0080446c2 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -555,6 +555,15 @@ public:
// Section 3: Misc admin methods
+#if ENABLE(DFG_JIT)
+ Label labelIgnoringWatchpoints()
+ {
+ Label result;
+ result.m_label = m_assembler.labelIgnoringWatchpoints();
+ return result;
+ }
+#endif
+
Label label()
{
return Label(this);
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index 8c5606972..9c35be8b5 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -1730,6 +1730,11 @@ public:
m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
return result;
}
+
+ AssemblerLabel labelIgnoringWatchpoints()
+ {
+ return m_formatter.label();
+ }
AssemblerLabel label()
{
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 60596d1c2..bcbb51f63 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1583,7 +1583,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
, m_source(other.m_source)
, m_sourceOffset(other.m_sourceOffset)
#if ENABLE(JIT)
- , m_globalResolveInfos(other.m_globalResolveInfos)
+ , m_globalResolveInfos(other.m_globalResolveInfos.size())
#endif
#if ENABLE(VALUE_PROFILER)
, m_executionEntryCount(0)
@@ -1609,6 +1609,11 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
optimizeAfterWarmUp();
jitAfterWarmUp();
+#if ENABLE(JIT)
+ for (unsigned i = m_globalResolveInfos.size(); i--;)
+ m_globalResolveInfos[i] = GlobalResolveInfo(other.m_globalResolveInfos[i].bytecodeOffset);
+#endif
+
if (other.m_rareData) {
createRareDataIfNecessary();
@@ -2258,6 +2263,10 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
return false;
return true;
}
+GlobalResolveInfo& CodeBlock::globalResolveInfoForBytecodeOffset(unsigned bytecodeOffset)
+{
+ return *(binarySearch<GlobalResolveInfo, unsigned, getGlobalResolveInfoBytecodeOffset>(m_globalResolveInfos.begin(), m_globalResolveInfos.size(), bytecodeOffset));
+}
#endif
void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
@@ -2269,7 +2278,8 @@ void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
#endif
#if ENABLE(JIT)
m_structureStubInfos.shrinkToFit();
- m_globalResolveInfos.shrinkToFit();
+ if (shrinkMode == EarlyShrink)
+ m_globalResolveInfos.shrinkToFit();
m_callLinkInfos.shrinkToFit();
m_methodCallLinkInfos.shrinkToFit();
#endif
@@ -2454,6 +2464,16 @@ void CodeBlock::copyPostParseDataFromAlternative()
}
#if ENABLE(JIT)
+void CodeBlock::reoptimize()
+{
+ ASSERT(replacement() != this);
+ ASSERT(replacement()->alternative() == this);
+ replacement()->tallyFrequentExitSites();
+ replacement()->jettison();
+ countReoptimization();
+ optimizeAfterWarmUp();
+}
+
CodeBlock* ProgramCodeBlock::replacement()
{
return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 573d422d3..b73dcb2b6 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -69,7 +69,6 @@
#include <wtf/RefPtr.h>
#include <wtf/SegmentedVector.h>
#include <wtf/Vector.h>
-#include "StructureStubInfo.h"
namespace JSC {
@@ -553,6 +552,8 @@ namespace JSC {
}
GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
+ GlobalResolveInfo& globalResolveInfoForBytecodeOffset(unsigned bytecodeOffset);
+ unsigned numberOfGlobalResolveInfos() { return m_globalResolveInfos.size(); }
void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); }
size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
@@ -1104,15 +1105,7 @@ namespace JSC {
#endif
#if ENABLE(JIT)
- void reoptimize()
- {
- ASSERT(replacement() != this);
- ASSERT(replacement()->alternative() == this);
- replacement()->tallyFrequentExitSites();
- replacement()->jettison();
- countReoptimization();
- optimizeAfterWarmUp();
- }
+ void reoptimize();
#endif
#if ENABLE(VERBOSE_VALUE_PROFILE)
diff --git a/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h b/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h
index 5576cfacd..c466c750d 100644
--- a/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h
+++ b/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h
@@ -31,6 +31,8 @@
namespace JSC {
struct GlobalResolveInfo {
+ GlobalResolveInfo() { }
+
GlobalResolveInfo(unsigned bytecodeOffset)
: offset(0)
, bytecodeOffset(bytecodeOffset)
@@ -39,9 +41,14 @@ struct GlobalResolveInfo {
WriteBarrier<Structure> structure;
unsigned offset;
- unsigned bytecodeOffset;
+ unsigned bytecodeOffset; // Only valid in old JIT code. This means nothing in the DFG.
};
+inline unsigned getGlobalResolveInfoBytecodeOffset(GlobalResolveInfo* globalResolveInfo)
+{
+ return globalResolveInfo->bytecodeOffset;
+}
+
} // namespace JSC
#endif // GlobalResolveInfo_h
diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
new file mode 100644
index 000000000..ff138704c
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "ResolveGlobalStatus.h"
+
+#include "CodeBlock.h"
+#include "JSValue.h"
+#include "Structure.h"
+
+namespace JSC {
+
+static ResolveGlobalStatus computeForStructure(CodeBlock* codeBlock, Structure* structure, Identifier& identifier)
+{
+ unsigned attributesIgnored;
+ JSCell* specificValue;
+ size_t offset = structure->get(
+ *codeBlock->globalData(), identifier, attributesIgnored, specificValue);
+ if (offset == notFound)
+ return ResolveGlobalStatus();
+
+ return ResolveGlobalStatus(ResolveGlobalStatus::Simple, structure, offset, specificValue);
+}
+
+static ResolveGlobalStatus computeForLLInt(CodeBlock* codeBlock, unsigned bytecodeIndex, Identifier& identifier)
+{
+#if ENABLE(LLINT)
+ Instruction* instruction = codeBlock->instructions().begin() + bytecodeIndex;
+
+ ASSERT(instruction[0].u.opcode == llint_op_resolve_global);
+
+ Structure* structure = instruction[3].u.structure.get();
+ if (!structure)
+ return ResolveGlobalStatus();
+
+ return computeForStructure(codeBlock, structure, identifier);
+#else
+ UNUSED_PARAM(codeBlock);
+ UNUSED_PARAM(bytecodeIndex);
+ UNUSED_PARAM(identifier);
+ return ResolveGlobalStatus();
+#endif
+}
+
+ResolveGlobalStatus ResolveGlobalStatus::computeFor(CodeBlock* codeBlock, unsigned bytecodeIndex, Identifier& identifier)
+{
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ if (!codeBlock->numberOfGlobalResolveInfos())
+ return computeForLLInt(codeBlock, bytecodeIndex, identifier);
+
+ if (codeBlock->likelyToTakeSlowCase(bytecodeIndex))
+ return ResolveGlobalStatus(TakesSlowPath);
+
+ GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfoForBytecodeOffset(bytecodeIndex);
+
+ if (!globalResolveInfo.structure)
+ return computeForLLInt(codeBlock, bytecodeIndex, identifier);
+
+ return computeForStructure(codeBlock, globalResolveInfo.structure.get(), identifier);
+#else
+ return computeForLLInt(codeBlock, bytecodeIndex, identifier);
+#endif
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
new file mode 100644
index 000000000..4698332f7
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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.
+ */
+
+#ifndef ResolveGlobalStatus_h
+#define ResolveGlobalStatus_h
+
+#include "JSValue.h"
+#include <wtf/NotFound.h>
+
+namespace JSC {
+
+class CodeBlock;
+class Identifier;
+class Structure;
+
+class ResolveGlobalStatus {
+public:
+ enum State {
+ NoInformation,
+ Simple,
+ TakesSlowPath
+ };
+
+ ResolveGlobalStatus()
+ : m_state(NoInformation)
+ , m_structure(0)
+ , m_offset(notFound)
+ {
+ }
+
+ ResolveGlobalStatus(
+ State state, Structure* structure = 0, size_t offset = notFound,
+ JSValue specificValue = JSValue())
+ : m_state(state)
+ , m_structure(structure)
+ , m_offset(offset)
+ , m_specificValue(specificValue)
+ {
+ }
+
+ static ResolveGlobalStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
+
+ State state() const { return m_state; }
+
+ bool isSet() const { return m_state != NoInformation; }
+ bool operator!() const { return !isSet(); }
+ bool isSimple() const { return m_state == Simple; }
+ bool takesSlowPath() const { return m_state == TakesSlowPath; }
+
+ Structure* structure() const { return m_structure; }
+ size_t offset() const { return m_offset; }
+ JSValue specificValue() const { return m_specificValue; }
+
+private:
+ State m_state;
+ Structure* m_structure;
+ size_t m_offset;
+ JSValue m_specificValue;
+}; // class ResolveGlobalStatus
+
+} // namespace JSC
+
+#endif // ResolveGlobalStatus_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 317a08504..75611972e 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -28,6 +28,7 @@
#if ENABLE(DFG_JIT)
+#include "ArrayConstructor.h"
#include "CallLinkStatus.h"
#include "CodeBlock.h"
#include "DFGByteCodeCache.h"
@@ -35,6 +36,7 @@
#include "GetByIdStatus.h"
#include "MethodCallLinkStatus.h"
#include "PutByIdStatus.h"
+#include "ResolveGlobalStatus.h"
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
@@ -94,6 +96,10 @@ private:
void setIntrinsicResult(bool usesResult, int resultOperand, NodeIndex);
// Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
+ bool handleConstantInternalFunction(bool usesResult, int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
+ void handleGetByOffset(
+ int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
+ bool useInlineStorage, size_t offset);
void handleGetById(
int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
const GetByIdStatus&);
@@ -1124,7 +1130,12 @@ void ByteCodeParser::handleCall(Interpreter* interpreter, Instruction* currentIn
ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
NodeIndex callTarget = get(currentInstruction[1].u.operand);
- enum { ConstantFunction, LinkedFunction, UnknownFunction } callType;
+ enum {
+ ConstantFunction,
+ ConstantInternalFunction,
+ LinkedFunction,
+ UnknownFunction
+ } callType;
CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
m_inlineStackTop->m_profiledBlock, m_currentIndex);
@@ -1147,6 +1158,13 @@ void ByteCodeParser::handleCall(Interpreter* interpreter, Instruction* currentIn
m_graph.valueOfFunctionConstant(callTarget),
m_graph.valueOfFunctionConstant(callTarget)->executable());
#endif
+ } else if (m_graph.isInternalFunctionConstant(callTarget)) {
+ callType = ConstantInternalFunction;
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLog("Call at [@%lu, bc#%u] has an internal function constant: %p.\n",
+ m_graph.size(), m_currentIndex,
+ m_graph.valueOfInternalFunctionConstant(callTarget));
+#endif
} else if (callLinkStatus.isSet() && !callLinkStatus.couldTakeSlowPath()
&& !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
callType = LinkedFunction;
@@ -1179,6 +1197,16 @@ void ByteCodeParser::handleCall(Interpreter* interpreter, Instruction* currentIn
prediction = getPrediction();
nextOffset += OPCODE_LENGTH(op_call_put_result);
}
+
+ if (callType == ConstantInternalFunction) {
+ if (handleConstantInternalFunction(usesResult, resultOperand, m_graph.valueOfInternalFunctionConstant(callTarget), registerOffset, argumentCountIncludingThis, prediction, kind))
+ return;
+
+ // Can only handle this using the generic call handler.
+ addCall(interpreter, currentInstruction, op);
+ return;
+ }
+
JSFunction* expectedFunction;
Intrinsic intrinsic;
bool certainAboutExpectedFunction;
@@ -1210,7 +1238,7 @@ void ByteCodeParser::handleCall(Interpreter* interpreter, Instruction* currentIn
} else if (handleInlining(usesResult, currentInstruction[1].u.operand, callTarget, resultOperand, certainAboutExpectedFunction, expectedFunction, registerOffset, argumentCountIncludingThis, nextOffset, kind))
return;
}
-
+
addCall(interpreter, currentInstruction, op);
}
@@ -1567,6 +1595,60 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
}
}
+bool ByteCodeParser::handleConstantInternalFunction(
+ bool usesResult, int resultOperand, InternalFunction* function, int registerOffset,
+ int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind kind)
+{
+ // If we ever find that we have a lot of internal functions that we specialize for,
+ // then we should probably have some sort of hashtable dispatch, or maybe even
+ // dispatch straight through the MethodTable of the InternalFunction. But for now,
+ // it seems that this case is hit infrequently enough, and the number of functions
+ // we know about is small enough, that having just a linear cascade of if statements
+ // is good enough.
+
+ UNUSED_PARAM(registerOffset); // Remove this once we do more things to the arguments.
+ UNUSED_PARAM(prediction); // Remove this once we do more things.
+ UNUSED_PARAM(kind); // Remove this once we do more things.
+
+ if (function->classInfo() == &ArrayConstructor::s_info) {
+ // We could handle this but don't for now.
+ if (argumentCountIncludingThis != 1)
+ return false;
+
+ setIntrinsicResult(
+ usesResult, resultOperand,
+ addToGraph(Node::VarArg, NewArray, OpInfo(0), OpInfo(0)));
+ return true;
+ }
+
+ return false;
+}
+
+void ByteCodeParser::handleGetByOffset(
+ int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
+ bool useInlineStorage, size_t offset)
+{
+ NodeIndex propertyStorage;
+ size_t offsetOffset;
+ if (useInlineStorage) {
+ propertyStorage = base;
+ ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
+ offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
+ } else {
+ propertyStorage = addToGraph(GetPropertyStorage, base);
+ offsetOffset = 0;
+ }
+ set(destinationOperand,
+ addToGraph(
+ GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
+ propertyStorage));
+
+ StorageAccessData storageAccessData;
+ storageAccessData.offset = offset + offsetOffset;
+ storageAccessData.identifierNumber = identifierNumber;
+ m_graph.m_storageAccessData.append(storageAccessData);
+}
+
void ByteCodeParser::handleGetById(
int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
const GetByIdStatus& getByIdStatus)
@@ -1620,25 +1702,9 @@ void ByteCodeParser::handleGetById(
return;
}
- NodeIndex propertyStorage;
- size_t offsetOffset;
- if (useInlineStorage) {
- propertyStorage = base;
- ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
- offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
- } else {
- propertyStorage = addToGraph(GetPropertyStorage, base);
- offsetOffset = 0;
- }
- set(destinationOperand,
- addToGraph(
- GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
- propertyStorage));
-
- StorageAccessData storageAccessData;
- storageAccessData.offset = getByIdStatus.offset() + offsetOffset;
- storageAccessData.identifierNumber = identifierNumber;
- m_graph.m_storageAccessData.append(storageAccessData);
+ handleGetByOffset(
+ destinationOperand, prediction, base, identifierNumber, useInlineStorage,
+ getByIdStatus.offset());
}
void ByteCodeParser::prepareToParseBlock()
@@ -2648,10 +2714,39 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_resolve_global: {
SpeculatedType prediction = getPrediction();
+ unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[
+ currentInstruction[2].u.operand];
+
+ ResolveGlobalStatus status = ResolveGlobalStatus::computeFor(
+ m_inlineStackTop->m_profiledBlock, m_currentIndex,
+ m_codeBlock->identifier(identifierNumber));
+ if (status.isSimple()) {
+ ASSERT(status.structure());
+
+ NodeIndex globalObject = addStructureTransitionCheck(
+ m_inlineStackTop->m_codeBlock->globalObject(), status.structure());
+
+ if (status.specificValue()) {
+ ASSERT(status.specificValue().isCell());
+
+ set(currentInstruction[1].u.operand,
+ cellConstant(status.specificValue().asCell()));
+ } else {
+ handleGetByOffset(
+ currentInstruction[1].u.operand, prediction, globalObject,
+ identifierNumber, status.structure()->isUsingInlineStorage(),
+ status.offset());
+ }
+
+ m_globalResolveNumber++; // Skip over the unused global resolve info.
+
+ NEXT_OPCODE(op_resolve_global);
+ }
+
NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction));
m_graph.m_resolveGlobalData.append(ResolveGlobalData());
ResolveGlobalData& data = m_graph.m_resolveGlobalData.last();
- data.identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
+ data.identifierNumber = identifierNumber;
data.resolveInfoIndex = m_globalResolveNumber++;
set(currentInstruction[1].u.operand, resolve);
@@ -3077,6 +3172,8 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
}
m_constantRemap[i] = result.iterator->second;
}
+ for (unsigned i = 0; i < codeBlock->numberOfGlobalResolveInfos(); ++i)
+ byteCodeParser->m_codeBlock->addGlobalResolveInfo(std::numeric_limits<unsigned>::max());
m_callsiteBlockHeadNeedsLinking = true;
} else {
@@ -3160,6 +3257,9 @@ void ByteCodeParser::parseCodeBlock()
ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex]->bytecodeBegin < m_currentIndex);
m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.m_blocks.size()));
m_inlineStackTop->m_blockLinkingTargets.append(m_graph.m_blocks.size());
+ // The first block is definitely an OSR target.
+ if (!m_graph.m_blocks.size())
+ block->isOSRTarget = true;
m_graph.m_blocks.append(block.release());
prepareToParseBlock();
}
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h
index 027b0f78b..1aec0bca1 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.h
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h
@@ -193,7 +193,6 @@ inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction
case op_put_scoped_var:
case op_resolve:
case op_resolve_base:
- case op_resolve_global:
// Constant buffers aren't copied correctly. This is easy to fix, but for
// now we just disable inlining for functions that use them.
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index fce76c68c..c9d3cbc32 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -134,6 +134,11 @@ enum NoResultTag { NoResult };
enum OptimizationFixpointState { FixpointConverged, FixpointNotConverged };
+inline bool shouldShowDisassembly()
+{
+ return Options::showDisassembly || Options::showDFGDisassembly;
+}
+
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
new file mode 100644
index 000000000..1dde37cf2
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "DFGDisassembler.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+Disassembler::Disassembler(Graph& graph)
+ : m_graph(graph)
+{
+ m_labelForBlockIndex.resize(graph.m_blocks.size());
+ m_labelForNodeIndex.resize(graph.size());
+}
+
+void Disassembler::dump(LinkBuffer& linkBuffer)
+{
+ m_graph.m_dominators.computeIfNecessary(m_graph);
+
+ dataLog("Generated JIT code for DFG CodeBlock %p:\n", m_graph.m_codeBlock);
+ dataLog(" Code at [%p, %p):\n", linkBuffer.debugAddress(), static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize());
+
+ const char* prefix = " ";
+ const char* disassemblyPrefix = " ";
+
+ NodeIndex lastNodeIndex = NoNode;
+ MacroAssembler::Label previousLabel = m_startOfCode;
+ for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNodeIndex);
+ m_graph.dumpBlockHeader(prefix, blockIndex, Graph::DumpLivePhisOnly);
+ NodeIndex lastNodeIndexForDisassembly = block->at(0);
+ for (size_t i = 0; i < block->size(); ++i) {
+ if (!m_graph[block->at(i)].willHaveCodeGen())
+ continue;
+ MacroAssembler::Label currentLabel;
+ if (m_labelForNodeIndex[block->at(i)].isSet())
+ currentLabel = m_labelForNodeIndex[block->at(i)];
+ else {
+ // Dump the last instruction by using the first label of the next block
+ // as the end point. This case is hit either during peephole compare
+ // optimizations (the Branch won't have its own label) or if we have a
+ // forced OSR exit.
+ if (blockIndex + 1 < m_graph.m_blocks.size())
+ currentLabel = m_labelForBlockIndex[blockIndex + 1];
+ else
+ currentLabel = m_endOfMainPath;
+ }
+ dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeIndexForDisassembly);
+ m_graph.dumpCodeOrigin(prefix, lastNodeIndex, block->at(i));
+ m_graph.dump(prefix, block->at(i));
+ lastNodeIndex = block->at(i);
+ lastNodeIndexForDisassembly = block->at(i);
+ }
+ }
+ dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, m_endOfMainPath, lastNodeIndex);
+ dataLog("%s(End Of Main Path)\n", prefix);
+ dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, NoNode);
+}
+
+void Disassembler::dumpDisassembly(const char* prefix, LinkBuffer& linkBuffer, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, NodeIndex context)
+{
+ size_t prefixLength = strlen(prefix);
+ int amountOfNodeWhiteSpace;
+ if (context == NoNode)
+ amountOfNodeWhiteSpace = 0;
+ else
+ amountOfNodeWhiteSpace = Graph::amountOfNodeWhiteSpace(m_graph[context]);
+ OwnArrayPtr<char> prefixBuffer = adoptArrayPtr(new char[prefixLength + amountOfNodeWhiteSpace + 1]);
+ strcpy(prefixBuffer.get(), prefix);
+ for (int i = 0; i < amountOfNodeWhiteSpace; ++i)
+ prefixBuffer[i + prefixLength] = ' ';
+ prefixBuffer[prefixLength + amountOfNodeWhiteSpace] = 0;
+
+ CodeLocationLabel start = linkBuffer.locationOf(previousLabel);
+ CodeLocationLabel end = linkBuffer.locationOf(currentLabel);
+ previousLabel = currentLabel;
+ ASSERT(bitwise_cast<uintptr_t>(end.executableAddress()) >= bitwise_cast<uintptr_t>(start.executableAddress()));
+ if (tryToDisassemble(start, bitwise_cast<uintptr_t>(end.executableAddress()) - bitwise_cast<uintptr_t>(start.executableAddress()), prefixBuffer.get(), WTF::dataFile()))
+ return;
+
+ dataLog("%s disassembly not available for range %p...%p\n", prefixBuffer.get(), start.executableAddress(), end.executableAddress());
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.h b/Source/JavaScriptCore/dfg/DFGDisassembler.h
new file mode 100644
index 000000000..470a989ef
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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.
+ */
+
+#ifndef DFGDisassembler_h
+#define DFGDisassembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "LinkBuffer.h"
+#include "MacroAssembler.h"
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+class Disassembler {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ Disassembler(Graph&);
+
+ void setStartOfCode(MacroAssembler::Label label) { m_startOfCode = label; }
+ void setForBlock(BlockIndex blockIndex, MacroAssembler::Label label)
+ {
+ m_labelForBlockIndex[blockIndex] = label;
+ }
+ void setForNode(NodeIndex nodeIndex, MacroAssembler::Label label)
+ {
+ m_labelForNodeIndex[nodeIndex] = label;
+ }
+ void setEndOfMainPath(MacroAssembler::Label label)
+ {
+ m_endOfMainPath = label;
+ }
+ void setEndOfCode(MacroAssembler::Label label)
+ {
+ m_endOfCode = label;
+ }
+
+ void dump(LinkBuffer&);
+
+private:
+ void dumpDisassembly(const char* prefix, LinkBuffer&, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, NodeIndex context);
+
+ Graph& m_graph;
+ MacroAssembler::Label m_startOfCode;
+ Vector<MacroAssembler::Label> m_labelForBlockIndex;
+ Vector<MacroAssembler::Label> m_labelForNodeIndex;
+ MacroAssembler::Label m_endOfMainPath;
+ MacroAssembler::Label m_endOfCode;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGDisassembler_h
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp
index e932792df..5033aa2c0 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp
@@ -43,11 +43,20 @@
namespace JSC { namespace DFG {
+static unsigned numCompilations;
+
+unsigned getNumCompilations()
+{
+ return numCompilations;
+}
+
enum CompileMode { CompileFunction, CompileOther };
inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr* jitCodeWithArityCheck)
{
SamplingRegion samplingRegion("DFG Compilation (Driver)");
+ numCompilations++;
+
ASSERT(codeBlock);
ASSERT(codeBlock->alternative());
ASSERT(codeBlock->alternative()->getJITType() == JITCode::BaselineJIT);
@@ -92,7 +101,6 @@ inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("DFG optimization fixpoint converged in %u iterations.\n", cnt);
#endif
- dfg.m_dominators.compute(dfg);
performVirtualRegisterAllocation(dfg);
GraphDumpMode modeForFinalValidate = DumpGraph;
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.h b/Source/JavaScriptCore/dfg/DFGDriver.h
index ce798d0a6..a6e82fef5 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.h
+++ b/Source/JavaScriptCore/dfg/DFGDriver.h
@@ -38,6 +38,8 @@ class MacroAssemblerCodePtr;
namespace DFG {
+JS_EXPORT_PRIVATE unsigned getNumCompilations();
+
#if ENABLE(DFG_JIT)
bool tryCompile(ExecState*, CodeBlock*, JITCode&);
bool tryCompileFunction(ExecState*, CodeBlock*, JITCode&, MacroAssemblerCodePtr& jitCodeWithArityCheck);
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 93de024d7..4689470c8 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -89,7 +89,7 @@ static void printWhiteSpace(unsigned amount)
dataLog(" ");
}
-void Graph::dumpCodeOrigin(NodeIndex prevNodeIndex, NodeIndex nodeIndex)
+void Graph::dumpCodeOrigin(const char* prefix, NodeIndex prevNodeIndex, NodeIndex nodeIndex)
{
if (prevNodeIndex == NoNode)
return;
@@ -112,18 +112,30 @@ void Graph::dumpCodeOrigin(NodeIndex prevNodeIndex, NodeIndex nodeIndex)
// Print the pops.
for (unsigned i = previousInlineStack.size(); i-- > indexOfDivergence;) {
+ dataLog("%s", prefix);
printWhiteSpace(i * 2);
dataLog("<-- %p\n", previousInlineStack[i].inlineCallFrame->executable.get());
}
// Print the pushes.
for (unsigned i = indexOfDivergence; i < currentInlineStack.size(); ++i) {
+ dataLog("%s", prefix);
printWhiteSpace(i * 2);
dataLog("--> %p\n", currentInlineStack[i].inlineCallFrame->executable.get());
}
}
-void Graph::dump(NodeIndex nodeIndex)
+int Graph::amountOfNodeWhiteSpace(Node& node)
+{
+ return (node.codeOrigin.inlineDepth() - 1) * 2;
+}
+
+void Graph::printNodeWhiteSpace(Node& node)
+{
+ printWhiteSpace(amountOfNodeWhiteSpace(node));
+}
+
+void Graph::dump(const char* prefix, NodeIndex nodeIndex)
{
Node& node = at(nodeIndex);
NodeType op = node.op();
@@ -134,7 +146,8 @@ void Graph::dump(NodeIndex nodeIndex)
if (mustGenerate)
--refCount;
- printWhiteSpace((node.codeOrigin.inlineDepth() - 1) * 2);
+ dataLog("%s", prefix);
+ printNodeWhiteSpace(node);
// Example/explanation of dataflow dump output
//
@@ -288,6 +301,54 @@ void Graph::dump(NodeIndex nodeIndex)
dataLog("\n");
}
+void Graph::dumpBlockHeader(const char* prefix, BlockIndex blockIndex, PhiNodeDumpMode phiNodeDumpMode)
+{
+ BasicBlock* block = m_blocks[blockIndex].get();
+
+ dataLog("%sBlock #%u (bc#%u): %s%s\n", prefix, (int)blockIndex, block->bytecodeBegin, block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "");
+ dataLog("%s Predecessors:", prefix);
+ for (size_t i = 0; i < block->m_predecessors.size(); ++i)
+ dataLog(" #%u", block->m_predecessors[i]);
+ dataLog("\n");
+ if (m_dominators.isValid()) {
+ dataLog("%s Dominated by:", prefix);
+ for (size_t i = 0; i < m_blocks.size(); ++i) {
+ if (!m_dominators.dominates(i, blockIndex))
+ continue;
+ dataLog(" #%lu", static_cast<unsigned long>(i));
+ }
+ dataLog("\n");
+ dataLog("%s Dominates:", prefix);
+ for (size_t i = 0; i < m_blocks.size(); ++i) {
+ if (!m_dominators.dominates(blockIndex, i))
+ continue;
+ dataLog(" #%lu", static_cast<unsigned long>(i));
+ }
+ dataLog("\n");
+ }
+ dataLog("%s Phi Nodes:", prefix);
+ unsigned count = 0;
+ for (size_t i = 0; i < block->phis.size(); ++i) {
+ NodeIndex phiNodeIndex = block->phis[i];
+ Node& phiNode = at(phiNodeIndex);
+ if (!phiNode.shouldGenerate() && phiNodeDumpMode == DumpLivePhisOnly)
+ continue;
+ if (!((++count) % 4))
+ dataLog("\n%s ", prefix);
+ dataLog(" @%u->(", phiNodeIndex);
+ if (phiNode.child1()) {
+ dataLog("@%u", phiNode.child1().index());
+ if (phiNode.child2()) {
+ dataLog(", @%u", phiNode.child2().index());
+ if (phiNode.child3())
+ dataLog(", @%u", phiNode.child3().index());
+ }
+ }
+ dataLog(")%s", i + 1 < block->phis.size() ? "," : "");
+ }
+ dataLog("\n");
+}
+
void Graph::dump()
{
NodeIndex lastNodeIndex = NoNode;
@@ -295,33 +356,7 @@ void Graph::dump()
BasicBlock* block = m_blocks[b].get();
if (!block)
continue;
- dataLog("Block #%u (bc#%u): %s%s\n", (int)b, block->bytecodeBegin, block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : "");
- dataLog(" Predecessors:");
- for (size_t i = 0; i < block->m_predecessors.size(); ++i)
- dataLog(" #%u", block->m_predecessors[i]);
- dataLog("\n");
- if (m_dominators.isValid()) {
- dataLog(" Dominated by:");
- for (size_t i = 0; i < m_blocks.size(); ++i) {
- if (!m_dominators.dominates(i, b))
- continue;
- dataLog(" #%lu", static_cast<unsigned long>(i));
- }
- dataLog("\n");
- dataLog(" Dominates:");
- for (size_t i = 0; i < m_blocks.size(); ++i) {
- if (!m_dominators.dominates(b, i))
- continue;
- dataLog(" #%lu", static_cast<unsigned long>(i));
- }
- dataLog("\n");
- }
- dataLog(" Phi Nodes:\n");
- for (size_t i = 0; i < block->phis.size(); ++i) {
- dumpCodeOrigin(lastNodeIndex, block->phis[i]);
- dump(block->phis[i]);
- lastNodeIndex = block->phis[i];
- }
+ dumpBlockHeader("", b, DumpAllPhis);
dataLog(" vars before: ");
if (block->cfaHasVisited)
dumpOperands(block->valuesAtHead, WTF::dataFile());
@@ -332,8 +367,8 @@ void Graph::dump()
dumpOperands(block->variablesAtHead, WTF::dataFile());
dataLog("\n");
for (size_t i = 0; i < block->size(); ++i) {
- dumpCodeOrigin(lastNodeIndex, block->at(i));
- dump(block->at(i));
+ dumpCodeOrigin("", lastNodeIndex, block->at(i));
+ dump("", block->at(i));
lastNodeIndex = block->at(i);
}
dataLog(" vars after: ");
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index acc9ff472..9e4a28fc3 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -179,11 +179,15 @@ public:
// CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
void dump();
- void dump(NodeIndex);
+ enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
+ void dumpBlockHeader(const char* prefix, BlockIndex, PhiNodeDumpMode);
+ void dump(const char* prefix, NodeIndex);
+ static int amountOfNodeWhiteSpace(Node&);
+ static void printNodeWhiteSpace(Node&);
// Dump the code origin of the given node as a diff from the code origin of the
// preceding node.
- void dumpCodeOrigin(NodeIndex, NodeIndex);
+ void dumpCodeOrigin(const char* prefix, NodeIndex, NodeIndex);
BlockIndex blockIndexForBytecodeOffset(Vector<BlockIndex>& blocks, unsigned bytecodeBegin);
@@ -273,6 +277,18 @@ public:
return false;
return true;
}
+ bool isInternalFunctionConstant(NodeIndex nodeIndex)
+ {
+ if (!isJSConstant(nodeIndex))
+ return false;
+ JSValue value = valueOfJSConstant(nodeIndex);
+ if (!value.isCell() || !value)
+ return false;
+ JSCell* cell = value.asCell();
+ if (!cell->inherits(&InternalFunction::s_info))
+ return false;
+ return true;
+ }
// Helper methods get constant values from nodes.
JSValue valueOfJSConstant(NodeIndex nodeIndex)
{
@@ -296,6 +312,10 @@ public:
ASSERT(function);
return jsCast<JSFunction*>(function);
}
+ InternalFunction* valueOfInternalFunctionConstant(NodeIndex nodeIndex)
+ {
+ return jsCast<InternalFunction*>(valueOfJSConstant(nodeIndex).asCell());
+ }
static const char *opName(NodeType);
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 561f51615..3c85cc77c 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -40,6 +40,15 @@
namespace JSC { namespace DFG {
+JITCompiler::JITCompiler(Graph& dfg)
+ : CCallHelpers(&dfg.m_globalData, dfg.m_codeBlock)
+ , m_graph(dfg)
+ , m_currentCodeOriginIndex(0)
+{
+ if (shouldShowDisassembly())
+ m_disassembler = adoptPtr(new Disassembler(dfg));
+}
+
void JITCompiler::linkOSRExits()
{
for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
@@ -201,9 +210,11 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
bool JITCompiler::compile(JITCode& entry)
{
+ setStartOfCode();
compileEntry();
SpeculativeJIT speculative(*this);
compileBody(speculative);
+ setEndOfMainPath();
// Generate slow path code.
speculative.runSlowPathGenerators();
@@ -213,6 +224,7 @@ bool JITCompiler::compile(JITCode& entry)
// Create OSR entry trampolines if necessary.
speculative.createOSREntries();
+ setEndOfCode();
LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock, JITCompilationCanFail);
if (linkBuffer.didFailToAllocate())
@@ -220,14 +232,18 @@ bool JITCompiler::compile(JITCode& entry)
link(linkBuffer);
speculative.linkOSREntries(linkBuffer);
+ if (m_disassembler)
+ m_disassembler->dump(linkBuffer);
+
entry = JITCode(
- FINALIZE_CODE(linkBuffer, ("DFG program/eval CodeBlock %p", m_codeBlock)),
+ linkBuffer.finalizeCodeWithoutDisassembly(),
JITCode::DFGJIT);
return true;
}
bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck)
{
+ setStartOfCode();
compileEntry();
// === Function header code generation ===
@@ -246,6 +262,7 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
// === Function body code generation ===
SpeculativeJIT speculative(*this);
compileBody(speculative);
+ setEndOfMainPath();
// === Function footer code generation ===
//
@@ -290,7 +307,7 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
// Create OSR entry trampolines if necessary.
speculative.createOSREntries();
-
+ setEndOfCode();
// === Link ===
LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock, JITCompilationCanFail);
@@ -302,10 +319,13 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
// FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs.
linkBuffer.link(callRegisterFileCheck, cti_register_file_check);
linkBuffer.link(callArityCheck, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck);
+
+ if (m_disassembler)
+ m_disassembler->dump(linkBuffer);
entryWithArityCheck = linkBuffer.locationOf(arityCheck);
entry = JITCode(
- FINALIZE_CODE(linkBuffer, ("DFG function CodeBlock %p", m_codeBlock)),
+ linkBuffer.finalizeCodeWithoutDisassembly(),
JITCode::DFGJIT);
return true;
}
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index 9d69ec9f3..ed16459cc 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "DFGCCallHelpers.h"
+#include "DFGDisassembler.h"
#include "DFGFPRInfo.h"
#include "DFGGPRInfo.h"
#include "DFGGraph.h"
@@ -208,12 +209,7 @@ struct PropertyAccessRecord {
// call to be linked).
class JITCompiler : public CCallHelpers {
public:
- JITCompiler(Graph& dfg)
- : CCallHelpers(&dfg.m_globalData, dfg.m_codeBlock)
- , m_graph(dfg)
- , m_currentCodeOriginIndex(0)
- {
- }
+ JITCompiler(Graph& dfg);
bool compile(JITCode& entry);
bool compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWithArityCheck);
@@ -221,6 +217,42 @@ public:
// Accessors for properties.
Graph& graph() { return m_graph; }
+ // Methods to set labels for the disassembler.
+ void setStartOfCode()
+ {
+ if (LIKELY(!m_disassembler))
+ return;
+ m_disassembler->setStartOfCode(labelIgnoringWatchpoints());
+ }
+
+ void setForBlock(BlockIndex blockIndex)
+ {
+ if (LIKELY(!m_disassembler))
+ return;
+ m_disassembler->setForBlock(blockIndex, labelIgnoringWatchpoints());
+ }
+
+ void setForNode(NodeIndex nodeIndex)
+ {
+ if (LIKELY(!m_disassembler))
+ return;
+ m_disassembler->setForNode(nodeIndex, labelIgnoringWatchpoints());
+ }
+
+ void setEndOfMainPath()
+ {
+ if (LIKELY(!m_disassembler))
+ return;
+ m_disassembler->setEndOfMainPath(labelIgnoringWatchpoints());
+ }
+
+ void setEndOfCode()
+ {
+ if (LIKELY(!m_disassembler))
+ return;
+ m_disassembler->setEndOfCode(labelIgnoringWatchpoints());
+ }
+
// Get a token for beginning a call, and set the current code origin index in
// the call frame.
CallBeginToken beginCall()
@@ -353,6 +385,8 @@ private:
// The dataflow graph currently being generated.
Graph& m_graph;
+ OwnPtr<Disassembler> m_disassembler;
+
// Vector of calls out from JIT code, including exception handler information.
// Count of the number of CallRecords with exception handlers.
Vector<CallLinkRecord> m_calls;
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 64e6fe097..40701c3bd 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -730,6 +730,11 @@ struct Node {
{
return m_refCount;
}
+
+ bool willHaveCodeGen()
+ {
+ return shouldGenerate() && op() != Phantom && op() != Nop;
+ }
unsigned refCount()
{
diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp b/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
index ca6257401..480a7dab9 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
+++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
@@ -46,19 +46,19 @@ const char* nodeFlagsAsString(NodeFlags flags)
if (flags & NodeResultMask) {
switch (flags & NodeResultMask) {
case NodeResultJS:
- ptr.strcat("ResultJS");
+ ptr.strcat("JS");
break;
case NodeResultNumber:
- ptr.strcat("ResultNumber");
+ ptr.strcat("Number");
break;
case NodeResultInt32:
- ptr.strcat("ResultInt32");
+ ptr.strcat("Int32");
break;
case NodeResultBoolean:
- ptr.strcat("ResultBoolean");
+ ptr.strcat("Boolean");
break;
case NodeResultStorage:
- ptr.strcat("ResultStorage");
+ ptr.strcat("Storage");
break;
default:
ASSERT_NOT_REACHED();
@@ -70,21 +70,21 @@ const char* nodeFlagsAsString(NodeFlags flags)
if (flags & NodeMustGenerate) {
if (hasPrinted)
ptr.strcat("|");
- ptr.strcat("MustGenerate");
+ ptr.strcat("MustGen");
hasPrinted = true;
}
if (flags & NodeHasVarArgs) {
if (hasPrinted)
ptr.strcat("|");
- ptr.strcat("HasVarArgs");
+ ptr.strcat("VarArgs");
hasPrinted = true;
}
if (flags & NodeClobbersWorld) {
if (hasPrinted)
ptr.strcat("|");
- ptr.strcat("ClobbersWorld");
+ ptr.strcat("Clobbers");
hasPrinted = true;
}
@@ -95,18 +95,23 @@ const char* nodeFlagsAsString(NodeFlags flags)
hasPrinted = true;
}
- if (flags & NodeUsedAsNumber) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("UsedAsNum");
- hasPrinted = true;
- }
-
- if (flags & NodeNeedsNegZero) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("NeedsNegZero");
- hasPrinted = true;
+ if (flags & NodeResultMask) {
+ if (!(flags & NodeUsedAsNumber) && !(flags & NodeNeedsNegZero)) {
+ if (hasPrinted)
+ ptr.strcat("|");
+ ptr.strcat("PureInt");
+ hasPrinted = true;
+ } else if (!(flags & NodeUsedAsNumber)) {
+ if (hasPrinted)
+ ptr.strcat("|");
+ ptr.strcat("PureInt(w/ neg zero)");
+ hasPrinted = true;
+ } else if (!(flags & NodeNeedsNegZero)) {
+ if (hasPrinted)
+ ptr.strcat("|");
+ ptr.strcat("PureNum");
+ hasPrinted = true;
+ }
}
if (flags & NodeMayOverflow) {
@@ -126,7 +131,7 @@ const char* nodeFlagsAsString(NodeFlags flags)
if (flags & NodeUsedAsInt) {
if (hasPrinted)
ptr.strcat("|");
- ptr.strcat("UsedAsInt");
+ ptr.strcat("UseAsInt");
hasPrinted = true;
}
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
index d46d59650..e617b5479 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
@@ -115,7 +115,10 @@ void OSRExitCompiler::handleExitCounts(const OSRExit& exit)
m_jit.store32(GPRInfo::regT2, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfForcedOSRExitCounter()));
m_jit.store32(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfSpeculativeSuccessCounter()));
+ m_jit.move(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), GPRInfo::regT0);
+
tooFewFails.append(m_jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(Options::forcedOSRExitCountForReoptimization)));
+
} else {
// Proceed based on the assumption that we can handle these exits so long as they
// don't get too frequent.
@@ -136,8 +139,14 @@ void OSRExitCompiler::handleExitCounts(const OSRExit& exit)
}
// Reoptimize as soon as possible.
- m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
- m_jit.store32(AssemblyHelpers::TrustedImm32(0), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
+#if !NUMBER_OF_ARGUMENT_REGISTERS
+ m_jit.poke(GPRInfo::regT0);
+#else
+ m_jit.move(GPRInfo::regT0, GPRInfo::argumentGPR0);
+ ASSERT(GPRInfo::argumentGPR0 != GPRInfo::regT1);
+#endif
+ m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(triggerReoptimizationNow)), GPRInfo::regT1);
+ m_jit.call(GPRInfo::regT1);
AssemblyHelpers::Jump doneAdjusting = m_jit.jump();
tooFewFails.link(&m_jit);
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 06a1cf883..b056a3c6d 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -32,14 +32,15 @@
#include "DFGRepatch.h"
#include "HostCallReturnValue.h"
#include "GetterSetter.h"
-#include <wtf/InlineASM.h>
#include "Interpreter.h"
+#include "JIT.h"
#include "JITExceptions.h"
#include "JSActivation.h"
#include "JSGlobalData.h"
#include "JSStaticScopeObject.h"
#include "NameInstance.h"
#include "Operations.h"
+#include <wtf/InlineASM.h>
#if ENABLE(DFG_JIT)
@@ -968,13 +969,11 @@ EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Iden
return JSValue::encode(base);
}
-EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResolveInfo* resolveInfo, Identifier* propertyName)
+EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResolveInfo* resolveInfo, JSGlobalObject* globalObject, Identifier* propertyName)
{
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
- JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-
PropertySlot slot(globalObject);
if (globalObject->getPropertySlot(exec, *propertyName, slot)) {
JSValue result = slot.getValue(exec, *propertyName);
@@ -1253,6 +1252,27 @@ void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void*
}
#endif
+extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
+{
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog("%p: Entered reoptimize\n", codeBlock);
+#endif
+ // We must be called with the baseline code block.
+ ASSERT(JITCode::isBaselineCode(codeBlock->getJITType()));
+
+ // If I am my own replacement, then reoptimization has already been triggered.
+ // This can happen in recursive functions.
+ if (codeBlock->replacement() == codeBlock)
+ return;
+
+ // Otherwise, the replacement must be optimized code. Use this as an opportunity
+ // to check our logic.
+ ASSERT(codeBlock->hasOptimizedReplacement());
+ ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
+
+ codeBlock->reoptimize();
+}
+
} // extern "C"
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index 38166a83f..7477ab2fc 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -65,7 +65,7 @@ typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EA)(ExecState*, JSArray*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECI)(ExecState*, JSCell*, Identifier*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue);
-typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EGI)(ExecState*, GlobalResolveInfo*, Identifier*);
+typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EGriJsgI)(ExecState*, GlobalResolveInfo*, JSGlobalObject*, Identifier*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EI)(ExecState*, Identifier*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJ)(ExecState*, EncodedJSValue);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJA)(ExecState*, EncodedJSValue, JSArray*);
@@ -121,7 +121,7 @@ void DFG_OPERATION operationNotifyGlobalVarWrite(WatchpointSet* watchpointSet) W
EncodedJSValue DFG_OPERATION operationResolve(ExecState*, Identifier*) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationResolveBase(ExecState*, Identifier*) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState*, Identifier*) WTF_INTERNAL;
-EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState*, GlobalResolveInfo*, Identifier*) WTF_INTERNAL;
+EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState*, GlobalResolveInfo*, JSGlobalObject*, Identifier*) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState*, EncodedJSValue) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationStrCat(ExecState*, void*, size_t) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationNewArray(ExecState*, void*, size_t) WTF_INTERNAL;
@@ -227,6 +227,8 @@ size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState*, EncodedJSValue) WTF_
void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void*) WTF_INTERNAL;
#endif
+void DFG_OPERATION triggerReoptimizationNow(CodeBlock*) WTF_INTERNAL;
+
} // extern "C"
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 852f74387..d9a79f13a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -1026,6 +1026,7 @@ void SpeculativeJIT::compile(BasicBlock& block)
for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
m_compileIndex = block[m_indexInBlock];
+ m_jit.setForNode(m_compileIndex);
Node& node = at(m_compileIndex);
m_codeOriginForOSR = node.codeOrigin;
if (!node.shouldGenerate()) {
@@ -1321,6 +1322,7 @@ bool SpeculativeJIT::compile()
ASSERT(!m_compileIndex);
for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
+ m_jit.setForBlock(m_block);
BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
if (block)
compile(*block);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 933784685..6c6948b90 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -1229,9 +1229,9 @@ public:
m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
return call;
}
- JITCompiler::Call callOperation(J_DFGOperation_EGI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
+ JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
{
- m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
+ m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
return appendCallWithExceptionCheckSetResult(operation, result);
}
JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg result, Identifier* identifier)
@@ -1482,9 +1482,9 @@ public:
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
- JITCompiler::Call callOperation(J_DFGOperation_EGI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, Identifier* identifier)
+ JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, Identifier* identifier)
{
- m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
+ m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
@@ -2369,7 +2369,7 @@ public:
Vector<SlowPathGenerator*, 8> m_slowPathGenerators; // doesn't use OwnPtr<> because I don't want to include DFGSlowPathGenerator.h
Vector<SilentRegisterSavePlan> m_plans;
-
+
ValueRecovery computeValueRecoveryFor(const ValueSource&);
ValueRecovery computeValueRecoveryFor(int operand)
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 0c33e0748..21d94e9e8 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -3840,7 +3840,7 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(
slowPathCall(
structuresNotMatch, this, operationResolveGlobal,
- JSValueRegs(resultTagGPR, resultPayloadGPR), resolveInfoGPR,
+ JSValueRegs(resultTagGPR, resultPayloadGPR), resolveInfoGPR, globalObjectGPR,
&m_jit.codeBlock()->identifier(data.identifierNumber)));
jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 0b7606b2c..a6c283584 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -3843,11 +3843,11 @@ void SpeculativeJIT::compile(Node& node)
m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR);
m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr), resultGPR);
-
+
addSlowPathGenerator(
slowPathCall(
structuresDontMatch, this, operationResolveGlobal,
- resultGPR, resolveInfoGPR,
+ resultGPR, resolveInfoGPR, globalObjectGPR,
&m_jit.codeBlock()->identifier(data.identifierNumber)));
jsValueResult(resultGPR, m_compileIndex);
diff --git a/Source/JavaScriptCore/heap/HeapTimer.cpp b/Source/JavaScriptCore/heap/HeapTimer.cpp
index bc42032f5..b4d928a34 100644
--- a/Source/JavaScriptCore/heap/HeapTimer.cpp
+++ b/Source/JavaScriptCore/heap/HeapTimer.cpp
@@ -1,3 +1,28 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "HeapTimer.h"
diff --git a/Source/JavaScriptCore/heap/HeapTimer.h b/Source/JavaScriptCore/heap/HeapTimer.h
index ccd6ba8c5..fea013975 100644
--- a/Source/JavaScriptCore/heap/HeapTimer.h
+++ b/Source/JavaScriptCore/heap/HeapTimer.h
@@ -1,3 +1,28 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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.
+ */
+
#ifndef HeapTimer_h
#define HeapTimer_h
diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
index 0d0116f42..165bfeaff 100644
--- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
+++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
@@ -1,3 +1,28 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "IncrementalSweeper.h"
@@ -14,9 +39,10 @@ namespace JSC {
#if USE(CF)
-static const CFTimeInterval sweepTimeSlicePerBlock = 0.01;
-static const CFTimeInterval sweepTimeMultiplier = 1.0 / sweepTimeSlicePerBlock;
-
+static const CFTimeInterval sweepTimeSlice = .01; // seconds
+static const CFTimeInterval sweepTimeTotal = .10;
+static const CFTimeInterval sweepTimeMultiplier = 1.0 / sweepTimeTotal;
+
void IncrementalSweeper::doWork()
{
APIEntryShim shim(m_globalData);
@@ -26,7 +52,6 @@ void IncrementalSweeper::doWork()
IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
: HeapTimer(heap->globalData(), runLoop)
, m_currentBlockToSweepIndex(0)
- , m_lengthOfLastSweepIncrement(0.0)
{
}
@@ -37,7 +62,7 @@ PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
void IncrementalSweeper::scheduleTimer()
{
- CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + (m_lengthOfLastSweepIncrement * sweepTimeMultiplier));
+ CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + (sweepTimeSlice * sweepTimeMultiplier));
}
void IncrementalSweeper::cancelTimer()
@@ -47,14 +72,17 @@ void IncrementalSweeper::cancelTimer()
void IncrementalSweeper::doSweep(double sweepBeginTime)
{
- for (; m_currentBlockToSweepIndex < m_blocksToSweep.size(); m_currentBlockToSweepIndex++) {
- MarkedBlock* nextBlock = m_blocksToSweep[m_currentBlockToSweepIndex];
- if (!nextBlock->needsSweeping())
+ while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
+ MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++];
+ if (!block->needsSweeping())
+ continue;
+
+ block->sweep();
+
+ CFTimeInterval elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime;
+ if (elapsedTime < sweepTimeSlice)
continue;
- nextBlock->sweep();
- m_blocksToSweep[m_currentBlockToSweepIndex++] = 0;
- m_lengthOfLastSweepIncrement = WTF::monotonicallyIncreasingTime() - sweepBeginTime;
scheduleTimer();
return;
}
diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h
index 80d674ca9..20f4e3ca8 100644
--- a/Source/JavaScriptCore/heap/IncrementalSweeper.h
+++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h
@@ -1,3 +1,28 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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.
+ */
+
#ifndef IncrementalSweeper_h
#define IncrementalSweeper_h
@@ -27,7 +52,6 @@ private:
void cancelTimer();
unsigned m_currentBlockToSweepIndex;
- double m_lengthOfLastSweepIncrement;
Vector<MarkedBlock*> m_blocksToSweep;
#else
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 06190f118..7eb57479b 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -45,7 +45,6 @@
#elif OS(UNIX)
-#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -142,8 +141,10 @@ MachineThreads::MachineThreads(Heap* heap)
MachineThreads::~MachineThreads()
{
- if (m_threadSpecific)
- ThreadSpecificKeyDelete(m_threadSpecific);
+ if (m_threadSpecific) {
+ int error = pthread_key_delete(m_threadSpecific);
+ ASSERT_UNUSED(error, !error);
+ }
MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
for (Thread* t = m_registeredThreads; t;) {
@@ -180,17 +181,19 @@ void MachineThreads::makeUsableFromMultipleThreads()
if (m_threadSpecific)
return;
- ThreadSpecificKeyCreate(&m_threadSpecific, removeThread);
+ int error = pthread_key_create(&m_threadSpecific, removeThread);
+ if (error)
+ CRASH();
}
void MachineThreads::addCurrentThread()
{
ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
- if (!m_threadSpecific || ThreadSpecificGet(m_threadSpecific))
+ if (!m_threadSpecific || pthread_getspecific(m_threadSpecific))
return;
- ThreadSpecificSet(m_threadSpecific, this);
+ pthread_setspecific(m_threadSpecific, this);
Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
MutexLocker lock(m_registeredThreadsMutex);
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.h b/Source/JavaScriptCore/heap/MachineStackMarker.h
index 2209f97e9..0f5a4c3aa 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.h
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.h
@@ -22,8 +22,8 @@
#ifndef MachineThreads_h
#define MachineThreads_h
+#include <pthread.h>
#include <wtf/Noncopyable.h>
-#include <wtf/ThreadSpecific.h>
#include <wtf/ThreadingPrimitives.h>
namespace JSC {
@@ -55,7 +55,7 @@ namespace JSC {
Heap* m_heap;
Mutex m_registeredThreadsMutex;
Thread* m_registeredThreads;
- WTF::ThreadSpecificKey m_threadSpecific;
+ pthread_key_t m_threadSpecific;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
index 9552a54ea..9cac906a1 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
@@ -107,8 +107,10 @@ void MarkedAllocator::addBlock(MarkedBlock* block)
void MarkedAllocator::removeBlock(MarkedBlock* block)
{
- if (m_currentBlock == block)
- m_currentBlock = 0;
+ if (m_currentBlock == block) {
+ m_currentBlock = static_cast<MarkedBlock*>(m_currentBlock->next());
+ m_freeList = MarkedBlock::FreeList();
+ }
m_blockList.remove(block);
}
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp
index 42247a385..a742d8d9a 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp
@@ -30,38 +30,37 @@ namespace JSC {
class Structure;
-class Take {
+class Free {
public:
typedef MarkedBlock* ReturnType;
- enum TakeMode { TakeIfEmpty, TakeAll };
+ enum FreeMode { FreeOrShrink, FreeAll };
- Take(TakeMode, MarkedSpace*);
+ Free(FreeMode, MarkedSpace*);
void operator()(MarkedBlock*);
ReturnType returnValue();
private:
- TakeMode m_takeMode;
+ FreeMode m_freeMode;
MarkedSpace* m_markedSpace;
DoublyLinkedList<MarkedBlock> m_blocks;
};
-inline Take::Take(TakeMode takeMode, MarkedSpace* newSpace)
- : m_takeMode(takeMode)
+inline Free::Free(FreeMode freeMode, MarkedSpace* newSpace)
+ : m_freeMode(freeMode)
, m_markedSpace(newSpace)
{
}
-inline void Take::operator()(MarkedBlock* block)
+inline void Free::operator()(MarkedBlock* block)
{
- if (m_takeMode == TakeIfEmpty && !block->isEmpty())
- return;
-
- m_markedSpace->allocatorFor(block).removeBlock(block);
- m_blocks.append(block);
+ if (m_freeMode == FreeOrShrink)
+ m_markedSpace->freeOrShrinkBlock(block);
+ else
+ m_markedSpace->freeBlock(block);
}
-inline Take::ReturnType Take::returnValue()
+inline Free::ReturnType Free::returnValue()
{
return m_blocks.head();
}
@@ -93,9 +92,8 @@ MarkedSpace::MarkedSpace(Heap* heap)
MarkedSpace::~MarkedSpace()
{
- // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
- Take take(Take::TakeAll, this);
- freeBlocks(forEachBlock(take));
+ Free free(Free::FreeAll, this);
+ forEachBlock(free);
}
struct LastChanceToFinalize : MarkedBlock::VoidFunctor {
@@ -160,17 +158,21 @@ bool MarkedSpace::isPagedOut(double deadline)
return false;
}
-void MarkedSpace::freeBlocks(MarkedBlock* head)
+void MarkedSpace::freeBlock(MarkedBlock* block)
{
- MarkedBlock* next;
- for (MarkedBlock* block = head; block; block = next) {
- next = static_cast<MarkedBlock*>(block->next());
-
- m_blocks.remove(block);
- block->sweep();
+ allocatorFor(block).removeBlock(block);
+ m_blocks.remove(block);
+ m_heap->blockAllocator().deallocate(MarkedBlock::destroy(block));
+}
- m_heap->blockAllocator().deallocate(MarkedBlock::destroy(block));
+void MarkedSpace::freeOrShrinkBlock(MarkedBlock* block)
+{
+ if (!block->isEmpty()) {
+ block->shrink();
+ return;
}
+
+ freeBlock(block);
}
struct Shrink : MarkedBlock::VoidFunctor {
@@ -179,11 +181,8 @@ struct Shrink : MarkedBlock::VoidFunctor {
void MarkedSpace::shrink()
{
- // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
- Take takeIfEmpty(Take::TakeIfEmpty, this);
- freeBlocks(forEachBlock(takeIfEmpty));
-
- forEachBlock<Shrink>();
+ Free freeOrShrink(Free::FreeOrShrink, this);
+ forEachBlock(freeOrShrink);
}
#if ENABLE(GGC)
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h
index 3f82bac96..62d4e5d9e 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.h
+++ b/Source/JavaScriptCore/heap/MarkedSpace.h
@@ -98,7 +98,8 @@ public:
template<typename Functor> typename Functor::ReturnType forEachBlock();
void shrink();
- void freeBlocks(MarkedBlock* head);
+ void freeBlock(MarkedBlock*);
+ void freeOrShrinkBlock(MarkedBlock*);
void didAddBlock(MarkedBlock*);
void didConsumeFreeList(MarkedBlock*);
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 2aca35146..e1e034b19 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -100,9 +100,10 @@ void JIT::emitOptimizationCheck(OptimizationCheckKind kind)
return;
Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop : Options::executionCounterIncrementForReturn), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter()));
- JITStubCall stubCall(this, kind == LoopOptimizationCheck ? cti_optimize_from_loop : cti_optimize_from_ret);
- if (kind == LoopOptimizationCheck)
- stubCall.addArgument(TrustedImm32(m_bytecodeOffset));
+ JITStubCall stubCall(this, cti_optimize);
+ stubCall.addArgument(TrustedImm32(m_bytecodeOffset));
+ if (kind == EnterOptimizationCheck)
+ ASSERT(!m_bytecodeOffset);
stubCall.call();
skipOptimize.link(this);
}
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 6491edbed..6d4c578c0 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -806,7 +806,7 @@ namespace JSC {
// Loads the character value of a single character string into dst.
void emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures);
- enum OptimizationCheckKind { LoopOptimizationCheck, RetOptimizationCheck };
+ enum OptimizationCheckKind { LoopOptimizationCheck, EnterOptimizationCheck };
#if ENABLE(DFG_JIT)
void emitOptimizationCheck(OptimizationCheckKind);
#else
diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp
index 81266052b..7d86e615f 100644
--- a/Source/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp
@@ -56,8 +56,6 @@ void JIT::emit_op_call_put_result(Instruction* instruction)
void JIT::emit_op_ret(Instruction* currentInstruction)
{
- emitOptimizationCheck(RetOptimizationCheck);
-
unsigned dst = currentInstruction[1].u.operand;
emitLoad(dst, regT1, regT0);
@@ -70,8 +68,6 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
{
- emitOptimizationCheck(RetOptimizationCheck);
-
unsigned result = currentInstruction[1].u.operand;
unsigned thisReg = currentInstruction[2].u.operand;
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index ad7a56e12..2e448dd52 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -576,8 +576,6 @@ void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
void JIT::emit_op_ret(Instruction* currentInstruction)
{
- emitOptimizationCheck(RetOptimizationCheck);
-
ASSERT(callFrameRegister != regT1);
ASSERT(regT1 != returnValueRegister);
ASSERT(returnValueRegister != callFrameRegister);
@@ -598,8 +596,6 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
{
- emitOptimizationCheck(RetOptimizationCheck);
-
ASSERT(callFrameRegister != regT1);
ASSERT(regT1 != returnValueRegister);
ASSERT(returnValueRegister != callFrameRegister);
@@ -1218,13 +1214,14 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
void JIT::emit_op_enter(Instruction*)
{
+ emitOptimizationCheck(EnterOptimizationCheck);
+
// Even though CTI doesn't use them, we initialize our constant
// registers to zap stale pointers, to avoid unnecessarily prolonging
// object lifetime and increasing GC pressure.
size_t count = m_codeBlock->m_numVars;
for (size_t j = 0; j < count; ++j)
emitInitRegister(j);
-
}
void JIT::emit_op_create_activation(Instruction* currentInstruction)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 57ef7ef2f..4f8589557 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -1487,6 +1487,8 @@ void JIT::emit_op_debug(Instruction* currentInstruction)
void JIT::emit_op_enter(Instruction*)
{
+ emitOptimizationCheck(EnterOptimizationCheck);
+
// Even though JIT code doesn't use them, we initialize our constant
// registers to zap stale pointers, to avoid unnecessarily prolonging
// object lifetime and increasing GC pressure.
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 12f3ec344..b0ff4a0c7 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -1919,17 +1919,16 @@ DEFINE_STUB_FUNCTION(void, op_check_has_instance)
}
#if ENABLE(DFG_JIT)
-DEFINE_STUB_FUNCTION(void, optimize_from_loop)
+DEFINE_STUB_FUNCTION(void, optimize)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
-
unsigned bytecodeIndex = stackFrame.args[0].int32();
-
+
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
+ dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
#endif
if (!codeBlock->checkIfOptimizationThresholdReached())
@@ -1937,7 +1936,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
if (codeBlock->hasOptimizedReplacement()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Considering loop OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
+ dataLog("Considering OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
#endif
if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
#if ENABLE(JIT_VERBOSE_OSR)
@@ -1959,14 +1958,14 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
JSObject* error = codeBlock->compileOptimized(callFrame, scopeChain);
#if ENABLE(JIT_VERBOSE_OSR)
if (error)
- dataLog("WARNING: optimized compilation from loop failed.\n");
+ dataLog("WARNING: optimized compilation failed.\n");
#else
UNUSED_PARAM(error);
#endif
if (codeBlock->replacement() == codeBlock) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from loop failed.\n", codeBlock);
+ dataLog("Optimizing %p failed.\n", codeBlock);
#endif
ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
@@ -1980,7 +1979,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from loop succeeded, performing OSR after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
+ dataLog("Optimizing %p succeeded, performing OSR after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
#endif
codeBlock->optimizeSoon();
@@ -1990,7 +1989,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
}
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from loop succeeded, OSR failed, after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
+ dataLog("Optimizing %p succeeded, OSR failed, after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
#endif
// Count the OSR failure as a speculation failure. If this happens a lot, then
@@ -1998,7 +1997,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
optimizedCodeBlock->countSpeculationFailure();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Encountered loop OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
+ dataLog("Encountered OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
#endif
// We are a lot more conservative about triggering reoptimization after OSR failure than
@@ -2011,7 +2010,7 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
// reoptimization trigger.
if (optimizedCodeBlock->shouldReoptimizeNow()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Triggering reoptimization of %p(%p) (in loop after OSR fail).\n", codeBlock, codeBlock->replacement());
+ dataLog("Triggering reoptimization of %p(%p) (after OSR fail).\n", codeBlock, codeBlock->replacement());
#endif
codeBlock->reoptimize();
return;
@@ -2021,71 +2020,6 @@ DEFINE_STUB_FUNCTION(void, optimize_from_loop)
// longer and then try again.
codeBlock->optimizeAfterWarmUp();
}
-
-DEFINE_STUB_FUNCTION(void, optimize_from_ret)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
-#endif
-
- if (!codeBlock->checkIfOptimizationThresholdReached())
- return;
-
- if (codeBlock->hasOptimizedReplacement()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Returning from old JIT call frame with optimized replacement %p(%p), with success/fail %u/%u", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
- CallFrame* callerFrame = callFrame->callerFrame();
- if (callerFrame)
- dataLog(", callerFrame = %p, returnPC = %p, caller code block = %p", callerFrame, callFrame->returnPC().value(), callerFrame->codeBlock());
- dataLog("\n");
-#endif
- if (codeBlock->replacement()->shouldReoptimizeNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Triggering reoptimization of %p(%p) (in return).\n", codeBlock, codeBlock->replacement());
-#endif
- codeBlock->reoptimize();
- }
-
- codeBlock->optimizeSoon();
- return;
- }
-
- if (!codeBlock->shouldOptimizeNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Delaying optimization for %p (in return) because of insufficient profiling.\n", codeBlock);
-#endif
- return;
- }
-
- ScopeChainNode* scopeChain = callFrame->scopeChain();
-
- JSObject* error = codeBlock->compileOptimized(callFrame, scopeChain);
- if (error)
- dataLog("WARNING: optimized compilation from ret failed.\n");
-
- if (codeBlock->replacement() == codeBlock) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from return failed.\n", codeBlock);
-#endif
-
- ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
- codeBlock->dontOptimizeAnytimeSoon();
- return;
- }
-
- ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from return succeeded after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
-#endif
-
- codeBlock->optimizeSoon();
-}
#endif // ENABLE(DFG_JIT)
DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index 251776075..d2bc15e64 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -450,8 +450,7 @@ extern "C" {
void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
void JIT_STUB cti_op_throw_reference_error(STUB_ARGS_DECLARATION) WTF_INTERNAL;
#if ENABLE(DFG_JIT)
- void JIT_STUB cti_optimize_from_loop(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_optimize_from_ret(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+ void JIT_STUB cti_optimize(STUB_ARGS_DECLARATION) WTF_INTERNAL;
#endif
void* JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL;
void* JIT_STUB cti_op_construct_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/offlineasm/offsets.rb b/Source/JavaScriptCore/offlineasm/offsets.rb
index 63af014bb..4f2734f86 100644
--- a/Source/JavaScriptCore/offlineasm/offsets.rb
+++ b/Source/JavaScriptCore/offlineasm/offsets.rb
@@ -23,8 +23,15 @@
require "ast"
-OFFSET_HEADER_MAGIC_NUMBERS = [ 0x9e43fd66, 0x4379bfba ]
-OFFSET_MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
+def to32Bit(value)
+ if value > 0x7fffffff
+ value -= 1 << 32
+ end
+ value
+end
+
+OFFSET_HEADER_MAGIC_NUMBERS = [ to32Bit(0x9e43fd66), to32Bit(0x4379bfba) ]
+OFFSET_MAGIC_NUMBERS = [ to32Bit(0xec577ac7), to32Bit(0x0ff5e755) ]
#
# MissingMagicValuesException
diff --git a/Source/JavaScriptCore/runtime/JSExportMacros.h b/Source/JavaScriptCore/runtime/JSExportMacros.h
index 19e2c286f..884805f86 100644
--- a/Source/JavaScriptCore/runtime/JSExportMacros.h
+++ b/Source/JavaScriptCore/runtime/JSExportMacros.h
@@ -36,7 +36,7 @@
// See note in wtf/Platform.h for more info on EXPORT_MACROS.
#if USE(EXPORT_MACROS)
-#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore)
+#if defined(BUILDING_JavaScriptCore)
#define JS_EXPORT_PRIVATE WTF_EXPORT
#else
#define JS_EXPORT_PRIVATE WTF_IMPORT
@@ -50,7 +50,7 @@
#if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
-#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore)
+#if defined(BUILDING_JavaScriptCore)
#define JS_EXPORTDATA __declspec(dllexport)
#else
#define JS_EXPORTDATA __declspec(dllimport)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 7b6109599..d38570dfb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -132,8 +132,6 @@ void JSGlobalObject::init(JSObject* thisValue)
{
ASSERT(JSLock::currentThreadIsHoldingLock());
- structure()->disableSpecificFunctionTracking();
-
m_globalScopeChain.set(globalData(), this, ScopeChainNode::create(0, this, &globalData(), this, thisValue));
JSGlobalObject::globalExec()->init(0, 0, m_globalScopeChain.get(), CallFrame::noCaller(), 0, 0);
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index aa71b8a7b..66cc89809 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -43,6 +43,16 @@
namespace JSC {
+JSCell* getCallableObjectSlow(JSCell* cell)
+{
+ Structure* structure = cell->structure();
+ if (structure->typeInfo().type() == JSFunctionType)
+ return cell;
+ if (structure->classInfo()->isSubClassOf(&InternalFunction::s_info))
+ return cell;
+ return 0;
+}
+
ASSERT_CLASS_FITS_IN_CELL(JSObject);
ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject);
ASSERT_CLASS_FITS_IN_CELL(JSFinalObject);
@@ -133,7 +143,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
for (JSObject* obj = thisObject; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
prototype = obj->prototype();
if (prototype.isNull()) {
- if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
+ if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -180,7 +190,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
break;
}
- if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
+ if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -196,7 +206,7 @@ void JSObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getJSFunction(value));
+ object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getCallableObject(value));
}
bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
@@ -226,7 +236,7 @@ void JSObject::putDirectAccessor(JSGlobalData& globalData, PropertyName property
ASSERT(value.isGetterSetter() && (attributes & Accessor));
PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getCallableObject(value));
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index ac8601deb..fdb708dd9 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -46,6 +46,15 @@ namespace JSC {
return 0;
}
+ JS_EXPORT_PRIVATE JSCell* getCallableObjectSlow(JSCell*);
+
+ inline JSCell* getCallableObject(JSValue value)
+ {
+ if (!value.isCell())
+ return 0;
+ return getCallableObjectSlow(value.asCell());
+ }
+
class GetterSetter;
class HashEntry;
class InternalFunction;
@@ -759,20 +768,20 @@ inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, PropertyName
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
ASSERT(!structure()->hasGetterSetterProperties());
- return putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value));
+ return putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value));
}
inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getCallableObject(value));
}
inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(!value.isGetterSetter());
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, 0, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, 0, slot, getCallableObject(value));
}
inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
@@ -781,7 +790,7 @@ inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, Prope
PropertyStorage newStorage = propertyStorage();
if (structure()->shouldGrowPropertyStorage())
newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
- size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(value));
+ size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value));
setPropertyStorage(globalData, newStorage, structure());
putDirectOffset(globalData, offset, value);
}
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 46fe72684..2f0dd42e5 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -35,7 +35,6 @@
#include "SymbolTable.h"
#include <wtf/UnusedParam.h>
#include <wtf/OwnArrayPtr.h>
-#include <wtf/UnusedParam.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index ec228f82a..7b6da6536 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -48,6 +48,7 @@ namespace JSC { namespace Options {
bool useJIT;
bool showDisassembly;
+bool showDFGDisassembly;
unsigned maximumOptimizationCandidateInstructionCount;
@@ -165,6 +166,7 @@ void initializeOptions()
SET(useJIT, true);
SET(showDisassembly, false);
+ SET(showDFGDisassembly, false);
SET(maximumOptimizationCandidateInstructionCount, 10000);
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index e5cc99590..0adb59e9b 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@ namespace JSC { namespace Options {
extern bool useJIT;
extern bool showDisassembly;
+extern bool showDFGDisassembly; // showDisassembly implies showDFGDisassembly.
extern unsigned maximumOptimizationCandidateInstructionCount;
diff --git a/Source/JavaScriptCore/shell/CMakeLists.txt b/Source/JavaScriptCore/shell/CMakeLists.txt
index 561d779dd..71b8963cc 100644
--- a/Source/JavaScriptCore/shell/CMakeLists.txt
+++ b/Source/JavaScriptCore/shell/CMakeLists.txt
@@ -20,5 +20,5 @@ IF (JSC_LINK_FLAGS)
ENDIF ()
IF (SHOULD_INSTALL_JS_SHELL)
- INSTALL(TARGETS ${JSC_EXECUTABLE_NAME} DESTINATION bin)
+ INSTALL(TARGETS ${JSC_EXECUTABLE_NAME} DESTINATION "${EXEC_INSTALL_DIR}")
ENDIF ()
diff --git a/Source/JavaScriptCore/wscript b/Source/JavaScriptCore/wscript
index 58696d9c5..4afb4d26a 100644
--- a/Source/JavaScriptCore/wscript
+++ b/Source/JavaScriptCore/wscript
@@ -66,7 +66,7 @@ def build(bld):
features = 'cc cxx cshlib',
includes = '. .. assembler ../WTF ' + ' '.join(includes),
source = sources,
- defines = ['BUILDING_JavaScriptCore', 'STATICALLY_LINKED_WITH_WTF'],
+ defines = ['BUILDING_JavaScriptCore'],
target = 'jscore',
uselib = 'WX ICU ' + get_config(),
uselib_local = '',