summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/ChangeLog291
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig10
-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/assembler/MacroAssemblerX86_64.h6
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h5
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp25
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h4
-rw-r--r--Source/JavaScriptCore/bytecode/Watchpoint.cpp1
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp10
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp43
-rw-r--r--Source/JavaScriptCore/dfg/DFGCSEPhase.cpp13
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h9
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.cpp1
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h10
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeType.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp43
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h13
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGRepatch.cpp17
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp72
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h23
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp20
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp18
-rw-r--r--Source/JavaScriptCore/dfg/DFGValueSource.h2
-rw-r--r--Source/JavaScriptCore/heap/JITStubRoutineSet.h25
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp14
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.h4
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp88
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h4
-rw-r--r--Source/JavaScriptCore/jsc.cpp11
-rw-r--r--Source/JavaScriptCore/offlineasm/armv7.rb6
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb66
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb20
-rw-r--r--Source/JavaScriptCore/offlineasm/config.rb31
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb69
-rw-r--r--Source/JavaScriptCore/offlineasm/transform.rb3
-rw-r--r--Source/JavaScriptCore/offlineasm/x86.rb6
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp58
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h7
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp20
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h9
46 files changed, 884 insertions, 216 deletions
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 10fca607d..4eeefa508 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,20 +1,285 @@
-2012-06-13 Patrick Gansterer <paroga@webkit.org>
+2012-07-23 Kent Tamura <tkent@chromium.org>
- [WIN] Remove dependency on pthread from MachineStackMarker
- https://bugs.webkit.org/show_bug.cgi?id=68429
+ Rename ENABLE_METER_TAG and ENABLE_PROGRESS_TAG to ENABLE_METER_ELEMENT and ENABLE_PROGRESS_ELEMENT respectively
+ https://bugs.webkit.org/show_bug.cgi?id=91941
- Reviewed by NOBODY (OOPS!).
+ Reviewed by Kentaro Hara.
- Implement pthread TLS functionality with native windows functions.
+ A flag name for an elmement should be ENABLE_*_ELEMENT.
- * 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:
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-07-22 Kent Tamura <tkent@chromium.org>
+
+ Rename ENABLE_DETAILS to ENABLE_DETAILS_ELEMENT
+ https://bugs.webkit.org/show_bug.cgi?id=91928
+
+ Reviewed by Kentaro Hara.
+
+ A flag name for an elmement should be ENABLE_*_ELEMENT.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-07-21 Patrick Gansterer <paroga@webkit.org>
+
+ [WIN] Use GetDateFormat and GetTimeFormat instead of strftime
+ https://bugs.webkit.org/show_bug.cgi?id=83436
+
+ Reviewed by Brent Fulgham.
+
+ The MS CRT implementation of strftime calls the same two functions.
+ Using them directly avoids the overhead of parsing the format string and removes
+ the dependency on strftime() for WinCE where this function does not exist.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+
+2012-07-20 Kent Tamura <tkent@chromium.org>
+
+ Rename ENABLE_DATALIST to ENABLE_DATALIST_ELEMENT
+ https://bugs.webkit.org/show_bug.cgi?id=91846
+
+ Reviewed by Kentaro Hara.
+
+ A flag name for an elmement should be ENABLE_*_ELEMENT.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-07-20 Han Shen <shenhan@google.com>
+
+ [Chromium] Compilation fails under gcc 4.7
+ https://bugs.webkit.org/show_bug.cgi?id=90227
+
+ Reviewed by Tony Chang.
+
+ Disable warnings about c++0x compatibility in gcc newer than 4.6.
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2012-07-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG cell checks should be hoisted
+ https://bugs.webkit.org/show_bug.cgi?id=91717
+
+ Reviewed by Geoffrey Garen.
+
+ The DFG has always had the policy of hoisting array and integer checks to
+ the point of variable assignment. Eventually, we added doubles and booleans
+ to the mix. But cells should really be part of this as well, particularly
+ for 32-bit where accessing a known-type variable is dramatically cheaper
+ than accessing a variable whose types is only predicted but otherwise
+ unproven.
+
+ This appears to be a definite speed-up for V8 on 32-bit, a possible speed-up
+ for Kraken, and a possible slow-down for V8 on 64-bit (around 0.2% if at
+ all). Any slow-downs can, and should, be addressed by making the hoisting
+ logic cognizant of variables that are never used in a manner that requires
+ type checks, and by sinking argument checks to the point(s) of first use.
+
+ To make this work I had to change some OSR machinery, and special-case the
+ type predictions of the 'this' argument for constructors. OSR exit normally
+ assumes that arguments are boxed, which happens to be true because the
+ type prediction used for check hoisting is LUB'd with the type of the
+ argument that was passed in - so either the arguments are always stored to
+ with the full tag+payload, or if only the payload is stored then the tag
+ matches whatever the caller would have set. But not so with the 'this'
+ argument for constructors, which is not initialized by the caller. We
+ could make this more precise by having argument types for OSR be inferred
+ using similar machinery to other locals, but I figured that for this patch
+ I should use the surgical fix.
+
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::branchTestPtr):
+ (MacroAssemblerX86_64):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::testq_rm):
+ (X86Assembler):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::isCreatedThisArgument):
+ (Graph):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGValueSource.h:
+ (JSC::DFG::ValueSource::forSpeculation):
+
+2012-07-19 Filip Pizlo <fpizlo@apple.com>
+
+ Fast path of storage resize should be removed from property storage reallocation, since it is only useful for arrays
+ https://bugs.webkit.org/show_bug.cgi?id=91796
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::emitPutTransitionStub):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::growOutOfLineStorage):
+
+2012-07-19 Mark Lam <mark.lam@apple.com>
+
+ Bug fixes and enhancements for OfflineASM annotation system.
+ https://bugs.webkit.org/show_bug.cgi?id=91690
+
+ Reviewed by Filip Pizlo.
+
+ * offlineasm/armv7.rb: added default handling of Instruction lower().
+ * offlineasm/asm.rb: added more support for annotations and more pretty printing.
+ * offlineasm/ast.rb: added more support for annotations.
+ * offlineasm/config.rb: added $preferredCommentStartColumn, simplified $enableInstrAnnotations.
+ * offlineasm/parser.rb: added more support for annotations.
+ * offlineasm/transform.rb: added more support for annotations.
+ * offlineasm/x86.rb: added default handling of Instruction lower().
+
+2012-07-19 Patrick Gansterer <paroga@webkit.org>
+
+ [WIN] Fix compilation of JSGlobalData.h with ENABLE(DFG_JIT)
+ https://bugs.webkit.org/show_bug.cgi?id=91243
+
+ Reviewed by Geoffrey Garen.
+
+ Disable MSVC warning 4200 "zero-sized array in struct/union" for JSC::ScratchBuffer.
+
+ * runtime/JSGlobalData.h:
+ (JSC):
+
+2012-07-19 Mark Lam <mark.lam@apple.com>
+
+ Fixed broken ENABLE_JIT=0 build.
+ https://bugs.webkit.org/show_bug.cgi?id=91725
+
+ Reviewed by Oliver Hunt.
+
+ * bytecode/Watchpoint.cpp:
+ * heap/JITStubRoutineSet.h:
+ (JSC):
+ (JITStubRoutineSet):
+ (JSC::JITStubRoutineSet::JITStubRoutineSet):
+ (JSC::JITStubRoutineSet::~JITStubRoutineSet):
+ (JSC::JITStubRoutineSet::add):
+ (JSC::JITStubRoutineSet::clearMarks):
+ (JSC::JITStubRoutineSet::mark):
+ (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines):
+ (JSC::JITStubRoutineSet::traceMarkedStubRoutines):
+
+2012-07-19 Kristóf Kosztyó <kkristof@inf.u-szeged.hu>
+
+ [Qt] Unreviewed buildfix after r123042.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpRegisters):
+
+2012-07-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should emit inline code for property storage (re)allocation
+ https://bugs.webkit.org/show_bug.cgi?id=91597
+
+ Reviewed by Oliver Hunt.
+
+ This adds two new ops to the DFG IR: AllocatePropertyStorage and
+ ReallocatePropertyStorage. It enables these to interact properly with
+ CSE so that a GetPropertyStorage on something for which we have
+ obviously done a (Re)AllocatePropertyStorage will result in the
+ GetPropertyStorage being eliminated. Other than that, the code
+ emitted for these ops is identical to the code we were emitting in
+ the corresponding PutById stub.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasStructureTransitionData):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/Structure.cpp:
+ (JSC::nextOutOfLineStorageCapacity):
+ * runtime/Structure.h:
+ (JSC):
+
+2012-07-16 Oliver Hunt <oliver@apple.com>
+
+ dumpCallFrame is broken in ToT
+ https://bugs.webkit.org/show_bug.cgi?id=91444
+
+ Reviewed by Gavin Barraclough.
+
+ Various changes have been made to the SF calling convention, but
+ dumpCallFrame has not been updated to reflect these changes.
+ That resulted in both bogus information, as well as numerous
+ assertions of sadness.
+
+ This patch makes dumpCallFrame actually work again and adds the
+ wonderful feature of telling you the name of the variable that a
+ register reflects, or what value it contains.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::nameForRegister):
+ A really innefficient mechanism for finding the name of a local register.
+ This should only ever be used by debug code so this should be okay.
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ Debug builds no longer throw away a functions symbol table, this allows
+ us to actually perform a register# to name mapping
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ We weren't propogating the bytecode offset here leading to assertions
+ in debug builds when dumping bytecode of DFG compiled code.
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::dumpRegisters):
+ Rework to actually be correct.
+ (JSC::getCallerInfo):
+ Return the byteocde offset as well now, given we have to determine it
+ anyway.
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ * interpreter/Interpreter.h:
+ (Interpreter):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionDumpCallFrame):
+ Give debug builds of JSC a method for calling dumpCallFrame so we can
+ inspect a callframe without requiring us to break in a debugger.
+
+2012-07-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG 32-bit PutById transition stub storage reallocation case copies the first pointer of each JSValue instead of the whole JSValue
+ https://bugs.webkit.org/show_bug.cgi?id=91599
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::emitPutTransitionStub):
2012-07-17 Filip Pizlo <fpizlo@apple.com>
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index dcea98333..31853f34c 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -48,9 +48,9 @@ ENABLE_CSS_VARIABLES = ;
ENABLE_CUSTOM_SCHEME_HANDLER = ;
ENABLE_DASHBOARD_SUPPORT = $(ENABLE_DASHBOARD_SUPPORT_$(REAL_PLATFORM_NAME));
ENABLE_DASHBOARD_SUPPORT_macosx = ENABLE_DASHBOARD_SUPPORT;
-ENABLE_DATALIST = ;
+ENABLE_DATALIST_ELEMENT = ;
ENABLE_DATA_TRANSFER_ITEMS = ;
-ENABLE_DETAILS = ENABLE_DETAILS;
+ENABLE_DETAILS_ELEMENT = ENABLE_DETAILS_ELEMENT;
ENABLE_DEVICE_ORIENTATION = ;
ENABLE_DIALOG_ELEMENT = ;
ENABLE_DIRECTORY_UPLOAD = ;
@@ -97,7 +97,7 @@ ENABLE_LINK_PRERENDER = ;
ENABLE_MATHML = ENABLE_MATHML;
ENABLE_MEDIA_SOURCE = ;
ENABLE_MEDIA_STATISTICS = ;
-ENABLE_METER_TAG = ENABLE_METER_TAG;
+ENABLE_METER_ELEMENT = ENABLE_METER_ELEMENT;
ENABLE_MHTML = ;
ENABLE_MICRODATA = ;
ENABLE_MUTATION_OBSERVERS = ENABLE_MUTATION_OBSERVERS;
@@ -107,7 +107,7 @@ ENABLE_NOTIFICATIONS_macosx_1070 = ;
ENABLE_NOTIFICATIONS_macosx_1080 = ENABLE_NOTIFICATIONS;
ENABLE_NOTIFICATIONS_macosx_1090 = ENABLE_NOTIFICATIONS;
ENABLE_PAGE_VISIBILITY_API = ;
-ENABLE_PROGRESS_TAG = ENABLE_PROGRESS_TAG;
+ENABLE_PROGRESS_ELEMENT = ENABLE_PROGRESS_ELEMENT;
ENABLE_QUOTA = ;
ENABLE_REGISTER_PROTOCOL_HANDLER = ;
ENABLE_REQUEST_ANIMATION_FRAME = ENABLE_REQUEST_ANIMATION_FRAME;
@@ -134,4 +134,4 @@ ENABLE_WEB_TIMING = ;
ENABLE_WORKERS = ENABLE_WORKERS;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT);
diff --git a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp b/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
index c60a2e68d..4f7a205e7 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 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 dfa38aafb..d8f838e87 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -163,6 +163,7 @@ EXPORTS
?displayName@JSFunction@JSC@@QAE?BVUString@2@PAVExecState@2@@Z
?dtoa@WTF@@YAXQADNAA_NAAHAAI@Z
?dumpAllOptions@Options@JSC@@SAXPAU_iobuf@@@Z
+ ?dumpCallFrame@Interpreter@JSC@@QAEXPAVExecState@2@@Z
?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
?empty@StringImpl@WTF@@SAPAV12@XZ
?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index 43bcddb64..f5af51323 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -476,6 +476,12 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
+ Jump branchTestPtr(ResultCondition cond, Address address, RegisterID reg)
+ {
+ m_assembler.testq_rm(reg, address.offset, address.base);
+ return Jump(m_assembler.jCC(x86Condition(cond)));
+ }
+
Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
if (mask.m_value == -1)
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index 83d681cf7..fc1c27245 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -997,6 +997,11 @@ public:
m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
}
+ void testq_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64(OP_TEST_EvGv, src, base, offset);
+ }
+
void testq_i32r(int imm, RegisterID dst)
{
m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index d417a5fbd..363efa28a 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -2942,4 +2942,29 @@ bool CodeBlock::usesOpcode(OpcodeID opcodeID)
return false;
}
+UString CodeBlock::nameForRegister(int registerNumber)
+{
+ SymbolTable::iterator end = m_symbolTable->end();
+ for (SymbolTable::iterator ptr = m_symbolTable->begin(); ptr != end; ++ptr) {
+ if (ptr->second.getIndex() == registerNumber)
+ return UString(ptr->first);
+ }
+ if (needsActivation() && registerNumber == activationRegister())
+ return "activation";
+ if (registerNumber == thisRegister())
+ return "this";
+ if (usesArguments()) {
+ if (registerNumber == argumentsRegister())
+ return "arguments";
+ if (unmodifiedArgumentsRegister(argumentsRegister()) == registerNumber)
+ return "real arguments";
+ }
+ if (registerNumber < 0) {
+ int argumentPosition = -registerNumber;
+ argumentPosition -= RegisterFile::CallFrameHeaderSize + 1;
+ return String::format("arguments[%3d]", argumentPosition - 1).impl();
+ }
+ return "";
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 56ede595a..2a7d2120a 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -578,7 +578,9 @@ namespace JSC {
void createActivation(CallFrame*);
void clearEvalCache();
-
+
+ UString nameForRegister(int registerNumber);
+
void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
{
m_propertyAccessInstructions.append(propertyAccessInstruction);
diff --git a/Source/JavaScriptCore/bytecode/Watchpoint.cpp b/Source/JavaScriptCore/bytecode/Watchpoint.cpp
index 6f80dfa5e..75dfe8a76 100644
--- a/Source/JavaScriptCore/bytecode/Watchpoint.cpp
+++ b/Source/JavaScriptCore/bytecode/Watchpoint.cpp
@@ -27,6 +27,7 @@
#include "Watchpoint.h"
#include "LinkBuffer.h"
+#include <wtf/PassRefPtr.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index b104788c8..33f282c66 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -193,8 +193,10 @@ JSObject* BytecodeGenerator::generate()
if (s_dumpsGeneratedCode)
m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
+#ifdef NDEBUG
if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
symbolTable().clear();
+#endif
m_codeBlock->shrinkToFit(CodeBlock::EarlyShrink);
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index e4561da06..01996f132 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -128,6 +128,8 @@ void AbstractState::initialize(Graph& graph)
root->valuesAtHead.argument(i).set(SpecFloat32Array);
else if (isFloat64ArraySpeculation(prediction))
root->valuesAtHead.argument(i).set(SpecFloat64Array);
+ else if (isCellSpeculation(prediction))
+ root->valuesAtHead.argument(i).set(SpecCell);
else
root->valuesAtHead.argument(i).makeTop();
@@ -272,7 +274,8 @@ bool AbstractState::execute(unsigned indexInBlock)
}
case SetLocal: {
- if (node.variableAccessData()->isCaptured()) {
+ if (node.variableAccessData()->isCaptured()
+ || m_graph.isCreatedThisArgument(node.local())) {
m_variables.operand(node.local()) = forNode(node.child1());
node.setCanExit(false);
break;
@@ -290,6 +293,9 @@ bool AbstractState::execute(unsigned indexInBlock)
else if (isArraySpeculation(predictedType)) {
node.setCanExit(!isArraySpeculation(forNode(node.child1()).m_type));
forNode(node.child1()).filter(SpecArray);
+ } else if (isCellSpeculation(predictedType)) {
+ node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
+ forNode(node.child1()).filter(SpecCell);
} else if (isBooleanSpeculation(predictedType))
speculateBooleanUnary(node);
else
@@ -1437,6 +1443,8 @@ bool AbstractState::execute(unsigned indexInBlock)
m_haveStructures = true;
break;
case GetPropertyStorage:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
node.setCanExit(false);
forNode(node.child1()).filter(SpecCell);
forNode(nodeIndex).clear(); // The result is not a JS value.
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 1b1395934..e4e94e90b 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -2271,7 +2271,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
m_graph.m_storageAccessData.append(storageAccessData);
} else if (!hasExitSite
&& putByIdStatus.isSimpleTransition()
- && putByIdStatus.oldStructure()->outOfLineCapacity() == putByIdStatus.newStructure()->outOfLineCapacity()
&& structureChainIsStillValid(
direct,
putByIdStatus.oldStructure(),
@@ -2293,20 +2292,38 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
}
ASSERT(putByIdStatus.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
- addToGraph(
- PutStructure,
- OpInfo(
- m_graph.addStructureTransitionData(
- StructureTransitionData(
- putByIdStatus.oldStructure(),
- putByIdStatus.newStructure()))),
- base);
NodeIndex propertyStorage;
- if (isInlineOffset(putByIdStatus.offset()))
- propertyStorage = base;
- else
- propertyStorage = addToGraph(GetPropertyStorage, base);
+ StructureTransitionData* transitionData =
+ m_graph.addStructureTransitionData(
+ StructureTransitionData(
+ putByIdStatus.oldStructure(),
+ putByIdStatus.newStructure()));
+
+ if (putByIdStatus.oldStructure()->outOfLineCapacity()
+ != putByIdStatus.newStructure()->outOfLineCapacity()) {
+
+ // If we're growing the property storage then it must be because we're
+ // storing into the out-of-line storage.
+ ASSERT(!isInlineOffset(putByIdStatus.offset()));
+
+ if (!putByIdStatus.oldStructure()->outOfLineCapacity()) {
+ propertyStorage = addToGraph(
+ AllocatePropertyStorage, OpInfo(transitionData), base);
+ } else {
+ propertyStorage = addToGraph(
+ ReallocatePropertyStorage, OpInfo(transitionData),
+ base, addToGraph(GetPropertyStorage, base));
+ }
+ } else {
+ if (isInlineOffset(putByIdStatus.offset()))
+ propertyStorage = base;
+ else
+ propertyStorage = addToGraph(GetPropertyStorage, base);
+ }
+
+ addToGraph(PutStructure, OpInfo(transitionData), base);
+
addToGraph(
PutByOffset,
OpInfo(m_graph.m_storageAccessData.size()),
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 04c3ebc66..4532214ee 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -465,6 +465,8 @@ private:
case NewArray:
case NewObject:
case CreateThis:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
return NoNode;
default:
@@ -581,6 +583,17 @@ private:
if (node.child1() == child1)
return index;
break;
+
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
+ // If we can cheaply prove this is a change to our object's storage, we
+ // can optimize and use its result.
+ if (node.child1() == child1)
+ return index;
+ // Otherwise, we currently can't prove that this doesn't change our object's
+ // storage, so we conservatively assume that it may change the storage
+ // pointer of any object, including ours.
+ return NoNode;
case PutByOffset:
case PutStructure:
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp
index 64fc0c7e5..f160b6d35 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp
@@ -64,7 +64,7 @@ inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
if (!Options::useDFGJIT())
return false;
-
+
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("DFG compiling code block %p(%p) for executable %p, number of instructions = %u.\n", codeBlock, codeBlock->alternative(), codeBlock->ownerExecutable(), codeBlock->instructionCount());
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 4091c48f7..3e6539353 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -441,6 +441,15 @@ public:
return m_codeBlock->usesArguments();
}
+ bool isCreatedThisArgument(int operand)
+ {
+ if (!operandIsArgument(operand))
+ return false;
+ if (operandToArgument(operand))
+ return false;
+ return m_codeBlock->specializationKind() == CodeForConstruct;
+ }
+
unsigned numSuccessors(BasicBlock* block)
{
return at(block->last()).numSuccessors();
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 5a9f972b8..ae28fad3f 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -188,6 +188,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
info.callType = m_jsCalls[i].m_callType;
info.isDFG = true;
+ info.bytecodeIndex = m_jsCalls[i].m_codeOrigin.bytecodeIndex;
linkBuffer.link(m_jsCalls[i].m_slowCall, FunctionPtr((m_globalData->getCTIStub(info.callType == CallLinkInfo::Construct ? linkConstructThunkGenerator : linkCallThunkGenerator)).code().executableAddress()));
info.callReturnLocation = linkBuffer.locationOfNearCall(m_jsCalls[i].m_slowCall);
info.hotPathBegin = linkBuffer.locationOf(m_jsCalls[i].m_targetToCheck);
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index ae07d5512..e72bd5e36 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -632,7 +632,15 @@ struct Node {
bool hasStructureTransitionData()
{
- return op() == PutStructure || op() == PhantomPutStructure;
+ switch (op()) {
+ case PutStructure:
+ case PhantomPutStructure:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
+ return true;
+ default:
+ return false;
+ }
}
StructureTransitionData& structureTransitionData()
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 7fcd2ec14..0ca0039b9 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -133,6 +133,8 @@ namespace JSC { namespace DFG {
macro(StructureTransitionWatchpoint, NodeMustGenerate) \
macro(PutStructure, NodeMustGenerate) \
macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
+ macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
+ macro(ReallocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
macro(GetPropertyStorage, NodeResultStorage) \
macro(GetIndexedPropertyStorage, NodeMustGenerate | NodeResultStorage) \
macro(GetByOffset, NodeResultJS) \
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 03c0666b7..9050d590e 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -28,6 +28,7 @@
#include "Arguments.h"
#include "CodeBlock.h"
+#include "CopiedSpaceInlineMethods.h"
#include "DFGOSRExit.h"
#include "DFGRepatch.h"
#include "DFGThunks.h"
@@ -894,7 +895,7 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ
return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
}
-inline void* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
+inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
JSGlobalData* globalData = &exec->globalData();
@@ -903,7 +904,7 @@ inline void* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
JSValue calleeAsValue = execCallee->calleeAsValue();
JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
if (!calleeAsFunctionCell)
- return handleHostCall(execCallee, calleeAsValue, kind);
+ return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
execCallee->setScopeChain(callee->scopeUnchecked());
@@ -918,7 +919,7 @@ inline void* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
if (error) {
globalData->exception = createStackOverflowError(exec);
- return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
+ return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
@@ -931,20 +932,20 @@ inline void* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
callLinkInfo.setSeen();
else
dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
- return codePtr.executableAddress();
+ return reinterpret_cast<char*>(codePtr.executableAddress());
}
-void* DFG_OPERATION operationLinkCall(ExecState* execCallee)
+char* DFG_OPERATION operationLinkCall(ExecState* execCallee)
{
return linkFor(execCallee, CodeForCall);
}
-void* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
+char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
{
return linkFor(execCallee, CodeForConstruct);
}
-inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
+inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
JSGlobalData* globalData = &exec->globalData();
@@ -953,7 +954,7 @@ inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
JSValue calleeAsValue = execCallee->calleeAsValue();
JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
if (UNLIKELY(!calleeAsFunctionCell))
- return handleHostCall(execCallee, calleeAsValue, kind);
+ return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
execCallee->setScopeChain(function->scopeUnchecked());
@@ -963,18 +964,18 @@ inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
if (error) {
exec->globalData().exception = error;
- return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
+ return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
}
- return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress();
+ return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
}
-void* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
+char* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
{
return virtualFor(execCallee, CodeForCall);
}
-void* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
+char* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
{
return virtualFor(execCallee, CodeForConstruct);
}
@@ -1241,6 +1242,24 @@ void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObj
base->putDirectOffset(globalData, offset, JSValue::decode(value));
}
+char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
+{
+ JSGlobalData& globalData = exec->globalData();
+ void* result;
+ if (!globalData.heap.tryAllocateStorage(initialOutOfLineCapacity * sizeof(JSValue), &result))
+ CRASH();
+ return reinterpret_cast<char*>(result);
+}
+
+char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
+{
+ JSGlobalData& globalData = exec->globalData();
+ void* result;
+ if (!globalData.heap.tryAllocateStorage(newSize, &result))
+ CRASH();
+ return reinterpret_cast<char*>(result);
+}
+
double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
{
return fmod(a, b);
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index 109dcb2eb..d0fbf7ed4 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -104,7 +104,8 @@ typedef void DFG_OPERATION (*V_DFGOperation_EJJJ)(ExecState*, EncodedJSValue, En
typedef void DFG_OPERATION (*V_DFGOperation_EJPP)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
typedef void DFG_OPERATION (*V_DFGOperation_EPZJ)(ExecState*, void*, int32_t, EncodedJSValue);
typedef void DFG_OPERATION (*V_DFGOperation_W)(WatchpointSet*);
-typedef void* DFG_OPERATION (*P_DFGOperation_E)(ExecState*);
+typedef char* DFG_OPERATION (*P_DFGOperation_E)(ExecState*);
+typedef char* DFG_OPERATION (*P_DFGOperation_ES)(ExecState*, size_t);
// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
JSCell* DFG_OPERATION operationNewObject(ExecState*) WTF_INTERNAL;
@@ -162,10 +163,10 @@ size_t DFG_OPERATION operationCompareGreaterEq(ExecState*, EncodedJSValue encode
size_t DFG_OPERATION operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
size_t DFG_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
size_t DFG_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
-void* DFG_OPERATION operationVirtualCall(ExecState*) WTF_INTERNAL;
-void* DFG_OPERATION operationLinkCall(ExecState*) WTF_INTERNAL;
-void* DFG_OPERATION operationVirtualConstruct(ExecState*) WTF_INTERNAL;
-void* DFG_OPERATION operationLinkConstruct(ExecState*) WTF_INTERNAL;
+char* DFG_OPERATION operationVirtualCall(ExecState*) WTF_INTERNAL;
+char* DFG_OPERATION operationLinkCall(ExecState*) WTF_INTERNAL;
+char* DFG_OPERATION operationVirtualConstruct(ExecState*) WTF_INTERNAL;
+char* DFG_OPERATION operationLinkConstruct(ExecState*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationCreateActivation(ExecState*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationCreateArguments(ExecState*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationCreateInlinedArguments(ExecState*, InlineCallFrame*) WTF_INTERNAL;
@@ -181,6 +182,8 @@ double DFG_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
size_t DFG_OPERATION operationIsObject(EncodedJSValue) WTF_INTERNAL;
size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
+char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
+char* DFG_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL;
// This method is used to lookup an exception hander, keyed by faultLocation, which is
// the return location from one of the calls out to one of the helper operations above.
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index d23cd8265..2e4f8094c 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -449,7 +449,9 @@ private:
}
case GetPropertyStorage:
- case GetIndexedPropertyStorage: {
+ case GetIndexedPropertyStorage:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage: {
changed |= setPrediction(SpecOther);
changed |= mergeDefaultFlags(node);
break;
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index cfc2cd664..19e064f2c 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -829,33 +829,18 @@ static void emitPutTransitionStub(
size_t oldSize = oldStructure->outOfLineCapacity() * sizeof(JSValue);
ASSERT(newSize > oldSize);
- // Optimistically assume that the old storage was the very last thing
- // allocated.
stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR3);
- stubJit.loadPtr(&copiedAllocator->m_currentPayloadEnd, scratchGPR2);
stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1);
- stubJit.subPtr(scratchGPR1, scratchGPR2);
- stubJit.subPtr(MacroAssembler::TrustedImm32(oldSize), scratchGPR2);
- MacroAssembler::Jump needFullRealloc =
- stubJit.branchPtr(MacroAssembler::NotEqual, scratchGPR2, scratchGPR3);
- slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize - oldSize), scratchGPR1));
- stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining);
- stubJit.move(scratchGPR2, scratchGPR1);
- MacroAssembler::Jump doneRealloc = stubJit.jump();
-
- needFullRealloc.link(&stubJit);
slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1));
stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining);
stubJit.negPtr(scratchGPR1);
stubJit.addPtr(MacroAssembler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR1);
stubJit.subPtr(MacroAssembler::TrustedImm32(newSize), scratchGPR1);
// We have scratchGPR1 = new storage, scratchGPR3 = old storage, scratchGPR2 = available
- for (size_t offset = 0; offset < oldSize; offset += sizeof(JSValue)) {
+ for (size_t offset = 0; offset < oldSize; offset += sizeof(void*)) {
stubJit.loadPtr(MacroAssembler::Address(scratchGPR3, offset), scratchGPR2);
stubJit.storePtr(scratchGPR2, MacroAssembler::Address(scratchGPR1, offset));
}
-
- doneRealloc.link(&stubJit);
}
stubJit.storePtr(scratchGPR1, MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()));
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index e8824b832..f368cf298 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -1241,7 +1241,8 @@ void SpeculativeJIT::checkArgumentTypes()
m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
- }
+ } else if (isCellSpeculation(predictedType))
+ speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, JITCompiler::addressFor(virtualRegister), GPRInfo::tagMaskRegister));
#else
if (isInt32Speculation(predictedType))
speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
@@ -1307,7 +1308,8 @@ void SpeculativeJIT::checkArgumentTypes()
speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
- }
+ } else if (isCellSpeculation(predictedType))
+ speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)));
#endif
}
m_isCheckingArgumentTypes = false;
@@ -3137,6 +3139,72 @@ bool SpeculativeJIT::compileRegExpExec(Node& node)
return true;
}
+void SpeculativeJIT::compileAllocatePropertyStorage(Node& node)
+{
+ SpeculateCellOperand base(this, node.child1());
+ GPRTemporary scratch(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg scratchGPR = scratch.gpr();
+
+ ASSERT(!node.structureTransitionData().previousStructure->outOfLineCapacity());
+ ASSERT(initialOutOfLineCapacity == node.structureTransitionData().newStructure->outOfLineCapacity());
+ size_t newSize = initialOutOfLineCapacity * sizeof(JSValue);
+ CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator();
+
+ m_jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR);
+ JITCompiler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize), scratchGPR);
+ m_jit.storePtr(scratchGPR, &copiedAllocator->m_currentRemaining);
+ m_jit.negPtr(scratchGPR);
+ m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR);
+ m_jit.subPtr(JITCompiler::TrustedImm32(newSize), scratchGPR);
+
+ addSlowPathGenerator(
+ slowPathCall(slowPath, this, operationAllocatePropertyStorageWithInitialCapacity, scratchGPR));
+
+ m_jit.storePtr(scratchGPR, JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()));
+
+ storageResult(scratchGPR, m_compileIndex);
+}
+
+void SpeculativeJIT::compileReallocatePropertyStorage(Node& node)
+{
+ SpeculateCellOperand base(this, node.child1());
+ StorageOperand oldStorage(this, node.child2());
+ GPRTemporary scratch1(this);
+ GPRTemporary scratch2(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg oldStorageGPR = oldStorage.gpr();
+ GPRReg scratchGPR1 = scratch1.gpr();
+ GPRReg scratchGPR2 = scratch2.gpr();
+
+ JITCompiler::Jump slowPath;
+
+ size_t oldSize = node.structureTransitionData().previousStructure->outOfLineCapacity() * sizeof(JSValue);
+ size_t newSize = oldSize * outOfLineGrowthFactor;
+ ASSERT(newSize == node.structureTransitionData().newStructure->outOfLineCapacity() * sizeof(JSValue));
+ CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator();
+
+ m_jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR2);
+ slowPath = m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize), scratchGPR2);
+ m_jit.storePtr(scratchGPR2, &copiedAllocator->m_currentRemaining);
+ m_jit.negPtr(scratchGPR2);
+ m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR2);
+ m_jit.subPtr(JITCompiler::TrustedImm32(newSize), scratchGPR2);
+
+ addSlowPathGenerator(
+ slowPathCall(slowPath, this, operationAllocatePropertyStorage, scratchGPR2, newSize));
+ // We have scratchGPR2 = new storage, scratchGPR1 = scratch
+ for (size_t offset = 0; offset < oldSize; offset += sizeof(void*)) {
+ m_jit.loadPtr(JITCompiler::Address(oldStorageGPR, offset), scratchGPR1);
+ m_jit.storePtr(scratchGPR1, JITCompiler::Address(scratchGPR2, offset));
+ }
+ m_jit.storePtr(scratchGPR2, JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()));
+
+ storageResult(scratchGPR2, m_compileIndex);
+}
+
} } // namespace JSC::DFG
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 487addd7f..cb7d89106 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -1151,6 +1151,16 @@ public:
// machine registers, and delegate the calling convention specific
// decision as to how to fill the regsiters to setupArguments* methods.
#if USE(JSVALUE64)
+ JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
+ {
+ m_jit.setupArgumentsExecState();
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result)
{
m_jit.setupArgumentsExecState();
@@ -1413,6 +1423,16 @@ public:
#define EABI_32BIT_DUMMY_ARG
#endif
+ JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
+ {
+ m_jit.setupArgumentsExecState();
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
{
prepareForExternalCall();
@@ -2048,6 +2068,9 @@ public:
bool compileStrictEq(Node&);
+ void compileAllocatePropertyStorage(Node&);
+ void compileReallocatePropertyStorage(Node&);
+
void compileGetCharCodeAt(Node&);
void compileGetByValOnString(Node&);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index ed98e0800..c63ba8c21 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -1918,7 +1918,7 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- if (isArraySpeculation(value.m_type)) {
+ if (isArraySpeculation(value.m_type) || isCellSpeculation(value.m_type)) {
GPRTemporary result(this);
m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
@@ -2010,7 +2010,7 @@ void SpeculativeJIT::compile(Node& node)
// OSR exit, would not be visible to the old JIT in any way.
m_codeOriginForOSR = nextNode->codeOrigin;
- if (!node.variableAccessData()->isCaptured()) {
+ if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) {
if (node.variableAccessData()->shouldUseDoubleFormat()) {
SpeculateDoubleOperand value(this, node.child1());
m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
@@ -2046,6 +2046,14 @@ void SpeculativeJIT::compile(Node& node)
recordSetLocal(node.local(), ValueSource(CellInRegisterFile));
break;
}
+ if (isCellSpeculation(predictedType)) {
+ SpeculateCellOperand cell(this, node.child1());
+ GPRReg cellGPR = cell.gpr();
+ m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
+ noResult(m_compileIndex);
+ recordSetLocal(node.local(), ValueSource(CellInRegisterFile));
+ break;
+ }
if (isBooleanSpeculation(predictedType)) {
SpeculateBooleanOperand value(this, node.child1());
m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
@@ -3542,6 +3550,14 @@ void SpeculativeJIT::compile(Node& node)
break;
}
+ case AllocatePropertyStorage:
+ compileAllocatePropertyStorage(node);
+ break;
+
+ case ReallocatePropertyStorage:
+ compileReallocatePropertyStorage(node);
+ break;
+
case GetPropertyStorage: {
SpeculateCellOperand base(this, node.child1());
GPRTemporary result(this, base);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 9e468e758..6dbb8a4b1 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -2052,7 +2052,7 @@ void SpeculativeJIT::compile(Node& node)
// OSR exit, would not be visible to the old JIT in any way.
m_codeOriginForOSR = nextNode->codeOrigin;
- if (!node.variableAccessData()->isCaptured()) {
+ if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) {
if (node.variableAccessData()->shouldUseDoubleFormat()) {
SpeculateDoubleOperand value(this, node.child1());
m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
@@ -2082,6 +2082,14 @@ void SpeculativeJIT::compile(Node& node)
recordSetLocal(node.local(), ValueSource(CellInRegisterFile));
break;
}
+ if (isCellSpeculation(predictedType)) {
+ SpeculateCellOperand cell(this, node.child1());
+ GPRReg cellGPR = cell.gpr();
+ m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
+ noResult(m_compileIndex);
+ recordSetLocal(node.local(), ValueSource(CellInRegisterFile));
+ break;
+ }
if (isBooleanSpeculation(predictedType)) {
SpeculateBooleanOperand boolean(this, node.child1());
m_jit.storePtr(boolean.gpr(), JITCompiler::addressFor(node.local()));
@@ -3557,6 +3565,14 @@ void SpeculativeJIT::compile(Node& node)
break;
}
+ case AllocatePropertyStorage:
+ compileAllocatePropertyStorage(node);
+ break;
+
+ case ReallocatePropertyStorage:
+ compileReallocatePropertyStorage(node);
+ break;
+
case GetPropertyStorage: {
SpeculateCellOperand base(this, node.child1());
GPRTemporary result(this, base);
diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.h b/Source/JavaScriptCore/dfg/DFGValueSource.h
index be4a6e081..f776137d0 100644
--- a/Source/JavaScriptCore/dfg/DFGValueSource.h
+++ b/Source/JavaScriptCore/dfg/DFGValueSource.h
@@ -130,7 +130,7 @@ public:
{
if (isInt32Speculation(prediction))
return ValueSource(Int32InRegisterFile);
- if (isArraySpeculation(prediction))
+ if (isArraySpeculation(prediction) || isCellSpeculation(prediction))
return ValueSource(CellInRegisterFile);
if (isBooleanSpeculation(prediction))
return ValueSource(BooleanInRegisterFile);
diff --git a/Source/JavaScriptCore/heap/JITStubRoutineSet.h b/Source/JavaScriptCore/heap/JITStubRoutineSet.h
index ea120132e..cb76ac8bd 100644
--- a/Source/JavaScriptCore/heap/JITStubRoutineSet.h
+++ b/Source/JavaScriptCore/heap/JITStubRoutineSet.h
@@ -28,8 +28,6 @@
#include <wtf/Platform.h>
-#if ENABLE(JIT)
-
#include "JITStubRoutine.h"
#include <wtf/FastAllocBase.h>
#include <wtf/HashMap.h>
@@ -40,6 +38,8 @@ namespace JSC {
class GCAwareJITStubRoutine;
class SlotVisitor;
+#if ENABLE(JIT)
+
class JITStubRoutineSet {
WTF_MAKE_NONCOPYABLE(JITStubRoutineSet);
WTF_MAKE_FAST_ALLOCATED;
@@ -72,9 +72,26 @@ private:
Vector<GCAwareJITStubRoutine*> m_listOfRoutines;
};
-} // namespace JSC
+#else // !ENABLE(JIT)
-#endif // ENABLE(JIT)
+class JITStubRoutineSet {
+ WTF_MAKE_NONCOPYABLE(JITStubRoutineSet);
+ WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ JITStubRoutineSet() { }
+ ~JITStubRoutineSet() { }
+
+ void add(GCAwareJITStubRoutine*) { }
+ void clearMarks() { }
+ void mark(void*) { }
+ void deleteUnmarkedJettisonedStubRoutines() { }
+ void traceMarkedStubRoutines(SlotVisitor&) { }
+};
+
+#endif // !ENABLE(JIT)
+
+} // namespace JSC
#endif // JITStubRoutineSet_h
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 8e0c57b6a..7eb57479b 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -141,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;) {
@@ -179,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 3d4aa22d4..5c7705fcf 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/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index b6072a5d6..3edb8589e 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -77,6 +77,8 @@ using namespace std;
namespace JSC {
+static CallFrame* getCallerInfo(JSGlobalData*, CallFrame*, int& lineNumber, unsigned& bytecodeOffset);
+
// Returns the depth of the scope chain within a given call frame.
static int depth(CodeBlock* codeBlock, ScopeChainNode* sc)
{
@@ -606,7 +608,13 @@ void Interpreter::initialize(LLInt::Data* llintData, bool canUseJIT)
#endif
}
-#ifndef NDEBUG
+#ifdef NDEBUG
+
+void Interpreter::dumpCallFrame(CallFrame*)
+{
+}
+
+#else
void Interpreter::dumpCallFrame(CallFrame* callFrame)
{
@@ -624,34 +632,42 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
CodeBlock* codeBlock = callFrame->codeBlock();
const Register* it;
const Register* end;
- JSValue v;
- it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters();
- v = (*it).jsValue();
-#if USE(JSVALUE32_64)
- dataLog("[this] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it;
-#else
- dataLog("[this] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it;
-#endif
- end = it + max(codeBlock->numParameters() - 1, 0); // - 1 to skip "this"
- if (it != end) {
- do {
- v = (*it).jsValue();
+ it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - callFrame->argumentCountIncludingThis();
+ end = callFrame->registers() - RegisterFile::CallFrameHeaderSize;
+ while (it < end) {
+ JSValue v = it->jsValue();
+ int registerNumber = it - callFrame->registers();
+ UString name = codeBlock->nameForRegister(registerNumber);
#if USE(JSVALUE32_64)
- dataLog("[param] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
+ dataLog("[r% 3d %14s] | %10p | %-16s 0x%llx \n", registerNumber, name.ascii().data(), it, v.description(), JSValue::encode(v));
#else
- dataLog("[param] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
+ dataLog("[r% 3d %14s] | %10p | %-16s %p \n", registerNumber, name.ascii().data(), it, v.description(), JSValue::encode(v));
#endif
- ++it;
- } while (it != end);
+ it++;
}
+
dataLog("-----------------------------------------------------------------------------\n");
- dataLog("[CodeBlock] | %10p | %p \n", it, (*it).codeBlock()); ++it;
- dataLog("[ScopeChain] | %10p | %p \n", it, (*it).scopeChain()); ++it;
- dataLog("[CallerRegisters] | %10p | %d \n", it, (*it).i()); ++it;
- dataLog("[ReturnPC] | %10p | %p \n", it, (*it).vPC()); ++it;
- dataLog("[ArgumentCount] | %10p | %d \n", it, (*it).i()); ++it;
- dataLog("[Callee] | %10p | %p \n", it, (*it).function()); ++it;
+ dataLog("[ArgumentCount] | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount());
+ ++it;
+ dataLog("[CallerFrame] | %10p | %p \n", it, callFrame->callerFrame());
+ ++it;
+ dataLog("[Callee] | %10p | %p \n", it, callFrame->callee());
+ ++it;
+ dataLog("[ScopeChain] | %10p | %p \n", it, callFrame->scopeChain());
+ ++it;
+#if ENABLE(JIT)
+ AbstractPC pc = callFrame->abstractReturnPC(callFrame->globalData());
+ if (pc.hasJITReturnAddress())
+ dataLog("[ReturnJITPC] | %10p | %p \n", it, pc.jitReturnAddress().value());
+#endif
+ unsigned bytecodeOffset = 0;
+ int line = 0;
+ getCallerInfo(&callFrame->globalData(), callFrame, line, bytecodeOffset);
+ dataLog("[ReturnVPC] | %10p | %d (line %d)\n", it, bytecodeOffset, line);
+ ++it;
+ dataLog("[CodeBlock] | %10p | %p \n", it, callFrame->codeBlock());
+ ++it;
dataLog("-----------------------------------------------------------------------------\n");
int registerCount = 0;
@@ -659,11 +675,13 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
end = it + codeBlock->m_numVars;
if (it != end) {
do {
- v = (*it).jsValue();
+ JSValue v = it->jsValue();
+ int registerNumber = it - callFrame->registers();
+ UString name = codeBlock->nameForRegister(registerNumber);
#if USE(JSVALUE32_64)
- dataLog("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
+ dataLog("[r% 3d %14s] | %10p | %-16s 0x%llx \n", registerNumber, name.ascii().data(), it, v.description(), JSValue::encode(v));
#else
- dataLog("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
+ dataLog("[r% 3d %14s] | %10p | %-16s %p \n", registerNumber, name.ascii().data(), it, v.description(), JSValue::encode(v));
#endif
++it;
++registerCount;
@@ -674,11 +692,11 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars;
if (it != end) {
do {
- v = (*it).jsValue();
+ JSValue v = (*it).jsValue();
#if USE(JSVALUE32_64)
- dataLog("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
+ dataLog("[r% 3d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
#else
- dataLog("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
+ dataLog("[r% 3d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
#endif
++it;
++registerCount;
@@ -838,10 +856,10 @@ static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFr
#endif
}
-static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber)
+static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber, unsigned& bytecodeOffset)
{
UNUSED_PARAM(globalData);
- unsigned bytecodeOffset = 0;
+ bytecodeOffset = 0;
lineNumber = -1;
ASSERT(!callFrame->hasHostCallFrameFlag());
CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag();
@@ -973,7 +991,8 @@ void Interpreter::getStackTrace(JSGlobalData* globalData, Vector<StackFrame>& re
StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, UString()};
results.append(s);
}
- callFrame = getCallerInfo(globalData, callFrame, line);
+ unsigned unusedBytecodeOffset = 0;
+ callFrame = getCallerInfo(globalData, callFrame, line, unusedBytecodeOffset);
}
}
@@ -5330,7 +5349,8 @@ JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction*
return jsNull();
int lineNumber;
- CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, lineNumber);
+ unsigned bytecodeOffset;
+ CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, lineNumber, bytecodeOffset);
if (!callerFrame)
return jsNull();
JSValue caller = callerFrame->callee();
@@ -5340,7 +5360,7 @@ JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction*
// Skip over function bindings.
ASSERT(caller.isObject());
while (asObject(caller)->inherits(&JSBoundFunction::s_info)) {
- callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, lineNumber);
+ callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, lineNumber, bytecodeOffset);
if (!callerFrame)
return jsNull();
caller = callerFrame->callee();
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index ba2f4fac4..8663bf8ec 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -248,6 +248,9 @@ namespace JSC {
void dumpSampleData(ExecState* exec);
void startSampling();
void stopSampling();
+
+ JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
+
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
@@ -279,7 +282,6 @@ namespace JSC {
JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
- void dumpCallFrame(CallFrame*);
void dumpRegisters(CallFrame*);
bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp
index 5f3dbdb99..00ad5d3b2 100644
--- a/Source/JavaScriptCore/jsc.cpp
+++ b/Source/JavaScriptCore/jsc.cpp
@@ -88,6 +88,7 @@ static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionGC(ExecState*);
#ifndef NDEBUG
static EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*);
#endif
static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*);
@@ -194,6 +195,7 @@ protected:
addFunction(globalData, "quit", functionQuit, 0);
addFunction(globalData, "gc", functionGC, 0);
#ifndef NDEBUG
+ addFunction(globalData, "dumpCallFrame", functionDumpCallFrame, 0);
addFunction(globalData, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
#endif
addFunction(globalData, "version", functionVersion, 1);
@@ -281,6 +283,15 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
return JSValue::encode(jsUndefined());
}
+#ifndef NDEBUG
+EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
+{
+ if (!exec->callerFrame()->hasHostCallFrameFlag())
+ exec->globalData().interpreter->dumpCallFrame(exec->callerFrame());
+ return JSValue::encode(jsUndefined());
+}
+#endif
+
EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
{
fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec)->value(exec).utf8().data());
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb
index 18538120b..6595fdc71 100644
--- a/Source/JavaScriptCore/offlineasm/armv7.rb
+++ b/Source/JavaScriptCore/offlineasm/armv7.rb
@@ -743,8 +743,8 @@ end
class Instruction
def lowerARMv7
- $asm.codeOrigin codeOriginString
- $asm.annotation annotation
+ $asm.codeOrigin codeOriginString if $enableCodeOriginComments
+ $asm.annotation annotation if $enableInstrAnnotations
case opcode
when "addi", "addp", "addis"
@@ -1012,7 +1012,7 @@ class Instruction
raise "Wrong number of arguments to smull in #{self.inspect} at #{codeOriginString}" unless operands.length == 4
$asm.puts "smull #{operands[2].armV7Operand}, #{operands[3].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
else
- raise "Unhandled opcode #{opcode} at #{codeOriginString}"
+ lowerDefault
end
end
end
diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb
index 0cf6320af..1603f4af4 100644
--- a/Source/JavaScriptCore/offlineasm/asm.rb
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -45,6 +45,8 @@ class Assembler
@codeOrigin = nil
@numLocalLabels = 0
@numGlobalLabels = 0
+
+ @newlineSpacerState = :none
end
def enterAsm
@@ -66,33 +68,60 @@ class Assembler
# Concatenates all the various components of the comment to dump.
def lastComment
+ separator = " "
result = ""
- result = " #{@comment} ." if @comment
- result += " #{@annotation} ." if @annotation and $enableTrailingInstrAnnotations
- result += " #{@internalComment} ." if @internalComment
- result += " #{@codeOrigin} ." if @codeOrigin and $enableCodeOriginComments
+ result = "#{@comment}" if @comment
+ if @annotation and $enableInstrAnnotations
+ result += separator if result != ""
+ result += "#{@annotation}"
+ end
+ if @internalComment
+ result += separator if result != ""
+ result += "#{@internalComment}"
+ end
+ if @codeOrigin and $enableCodeOriginComments
+ result += separator if result != ""
+ result += "#{@codeOrigin}"
+ end
if result != ""
- result = " //" + result
+ result = "// " + result
end
# Reset all the components that we've just sent to be dumped.
@commentState = :none
@comment = nil
- @internalComment = nil
@annotation = nil
@codeOrigin = nil
+ @internalComment = nil
result
end
- # Dumps the current instruction annotation in interlaced mode if appropriate.
- def putInterlacedAnnotation()
+ def formatDump(dumpStr, comment, commentColumns=$preferredCommentStartColumn)
+ if comment.length > 0
+ "%-#{commentColumns}s %s" % [dumpStr, comment]
+ else
+ dumpStr
+ end
+ end
+
+ # private method for internal use only.
+ def putAnnotation(text)
raise unless @state == :asm
- if $enableInterlacedInstrAnnotations
- @outp.puts(" // #{@annotation}") if @annotation
+ if $enableInstrAnnotations
+ @outp.puts text
@annotation = nil
end
end
+ def putLocalAnnotation()
+ putAnnotation " // #{@annotation}" if @annotation
+ end
+
+ def putGlobalAnnotation()
+ putsNewlineSpacerIfAppropriate(:annotation)
+ putAnnotation "// #{@annotation}" if @annotation
+ end
+
def putsLastComment
comment = lastComment
unless comment.empty?
@@ -102,8 +131,7 @@ class Assembler
def puts(*line)
raise unless @state == :asm
- putInterlacedAnnotation
- @outp.puts(" \"\\t" + line.join('') + "\\n\"#{lastComment}")
+ @outp.puts(formatDump(" \"\\t" + line.join('') + "\\n\"", lastComment))
end
def print(line)
@@ -111,12 +139,20 @@ class Assembler
@outp.print("\"" + line + "\"")
end
+ def putsNewlineSpacerIfAppropriate(state)
+ if @newlineSpacerState != state
+ @outp.puts("\n")
+ @newlineSpacerState = state
+ end
+ end
+
def putsLabel(labelName)
raise unless @state == :asm
@numGlobalLabels += 1
- @outp.puts("\n")
+ putsNewlineSpacerIfAppropriate(:global)
@internalComment = $enableLabelCountComments ? "Global Label #{@numGlobalLabels}" : nil
- @outp.puts("OFFLINE_ASM_GLOBAL_LABEL(#{labelName})#{lastComment}")
+ @outp.puts(formatDump("OFFLINE_ASM_GLOBAL_LABEL(#{labelName})", lastComment))
+ @newlineSpacerState = :none # After a global label, we can use another spacer.
end
def putsLocalLabel(labelName)
@@ -124,7 +160,7 @@ class Assembler
@numLocalLabels += 1
@outp.puts("\n")
@internalComment = $enableLabelCountComments ? "Local Label #{@numLocalLabels}" : nil
- @outp.puts("OFFLINE_ASM_LOCAL_LABEL(#{labelName})#{lastComment}")
+ @outp.puts(formatDump(" OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment))
end
def self.labelReference(labelName)
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index 86ad6bcb2..9333247dc 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -806,6 +806,17 @@ class Instruction < Node
def dump
"\t" + opcode.to_s + " " + operands.collect{|v| v.dump}.join(", ")
end
+
+ def lowerDefault
+ case opcode
+ when "localAnnotation"
+ $asm.putLocalAnnotation
+ when "globalAnnotation"
+ $asm.putGlobalAnnotation
+ else
+ raise "Unhandled opcode #{opcode} at #{codeOriginString}"
+ end
+ end
end
class Error < NoChildren
@@ -1180,7 +1191,7 @@ end
class Macro < Node
attr_reader :name, :variables, :body
-
+
def initialize(codeOrigin, name, variables, body)
super(codeOrigin)
@name = name
@@ -1202,14 +1213,15 @@ class Macro < Node
end
class MacroCall < Node
- attr_reader :name, :operands
+ attr_reader :name, :operands, :annotation
- def initialize(codeOrigin, name, operands)
+ def initialize(codeOrigin, name, operands, annotation)
super(codeOrigin)
@name = name
@operands = operands
raise unless @operands
@operands.each{|v| raise unless v}
+ @annotation = annotation
end
def children
@@ -1217,7 +1229,7 @@ class MacroCall < Node
end
def mapChildren(&proc)
- MacroCall.new(codeOrigin, @name, @operands.map(&proc))
+ MacroCall.new(codeOrigin, @name, @operands.map(&proc), @annotation)
end
def dump
diff --git a/Source/JavaScriptCore/offlineasm/config.rb b/Source/JavaScriptCore/offlineasm/config.rb
index ce1898170..e6287f367 100644
--- a/Source/JavaScriptCore/offlineasm/config.rb
+++ b/Source/JavaScriptCore/offlineasm/config.rb
@@ -21,6 +21,8 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
+$preferredCommentStartColumn = 70
+
# Turns on dumping of the count of labels.
# For example, the output will look like this:
@@ -45,32 +47,11 @@ $enableCodeOriginComments = true
# Turns on recording and dumping of annotations in the generated output file.
# An annotations can be specified for each instruction in the source asm files.
-#
-# $enableInterlacedInstrAnnotations will interlace the annotation between
-# instructions. For example, the output will look like this:
+# For example, the output will look like this:
#
# ...
-# // @ t2<CodeBlock> = cfr.CodeBlock
-# "\tmovq -8(%r13), %rcx\n"
-# // @ t2<size_t> = t2<CodeBlock>.m_numVars
-# "\tmovl 52(%rcx), %ecx\n"
+# "\tmovq -8(%r13), %rcx\n" // t2<CodeBlock> = cfr.CodeBlock
+# "\tmovl 52(%rcx), %ecx\n" // t2<size_t> = t2<CodeBlock>.m_numVars
# ...
#
-# $enableTrailingInstrAnnotations will insert the annotation in the trailing
-# comment after your instructions. For example, the output will look like this:
-#
-# ...
-# "\tmovq -8(%r13), %rcx\n" // @ t2<CodeBlock> = cfr.CodeBlock
-# "\tmovl 52(%rcx), %ecx\n" // @ t2<size_t> = t2<CodeBlock>.m_numVars
-# ...
-#
-# If both $enableInterlacedInstrAnnotations and $enableTrailingInstrAnnotations
-# are enabled, interlaced annotations will take precedence, and any available
-# annotations will only be dumped in the interlaced format.
-#
-$enableInterlacedInstrAnnotations = false
-$enableTrailingInstrAnnotations = false
-
-
-# Sanity check for annotation configs.
-$enableInstrAnnotations = ($enableInterlacedInstrAnnotations or $enableTrailingInstrAnnotations)
+$enableInstrAnnotations = false
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index 8696a61a9..70b03cf70 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -74,6 +74,15 @@ class Token
end
end
+class Annotation
+ attr_reader :codeOrigin, :type, :string
+ def initialize(codeOrigin, type, string)
+ @codeOrigin = codeOrigin
+ @type = type
+ @string = string
+ end
+end
+
#
# The lexer. Takes a string and returns an array of tokens.
#
@@ -83,17 +92,20 @@ def lex(str, fileName)
result = []
lineNumber = 1
annotation = nil
+ whitespaceFound = false
while not str.empty?
case str
when /\A\#([^\n]*)/
# comment, ignore
- when /\A\/\/([^\n]*)/
+ when /\A\/\/\ ?([^\n]*)/
# annotation
annotation = $1
+ annotationType = whitespaceFound ? :local : :global
when /\A\n/
# We've found a '\n'. Emit the last comment recorded if appropriate:
if $enableInstrAnnotations and annotation
- result << Token.new(CodeOrigin.new(fileName, lineNumber), "@" + annotation)
+ result << Annotation.new(CodeOrigin.new(fileName, lineNumber),
+ annotationType, annotation)
annotation = nil
end
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
@@ -106,6 +118,9 @@ def lex(str, fileName)
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A([ \t]+)/
# whitespace, ignore
+ whitespaceFound = true
+ str = $~.post_match
+ next
when /\A0x([0-9a-fA-F]+)/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&.hex.to_s)
when /\A0([0-7]+)/
@@ -119,6 +134,7 @@ def lex(str, fileName)
else
raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
end
+ whitespaceFound = false
str = $~.post_match
end
result
@@ -146,10 +162,6 @@ def isIdentifier(token)
token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
end
-def isAnnotation(token)
- token =~ /\A\@([^\n]*)/
-end
-
def isLabel(token)
token =~ /\A_([a-zA-Z0-9_]*)\Z/
end
@@ -175,6 +187,7 @@ class Parser
def initialize(data, fileName)
@tokens = lex(data, fileName)
@idx = 0
+ @annotation = nil
end
def parseError(*comment)
@@ -487,6 +500,20 @@ class Parser
loop {
if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
break
+ elsif @tokens[@idx].is_a? Annotation
+ # This is the only place where we can encounter a global
+ # annotation, and hence need to be able to distinguish between
+ # them.
+ # globalAnnotations are the ones that start from column 0. All
+ # others are considered localAnnotations. The only reason to
+ # distinguish between them is so that we can format the output
+ # nicely as one would expect.
+
+ codeOrigin = @tokens[@idx].codeOrigin
+ annotationOpcode = (@tokens[@idx].type == :global) ? "globalAnnotation" : "localAnnotation"
+ list << Instruction.new(codeOrigin, annotationOpcode, [], @tokens[@idx].string)
+ @annotation = nil
+ @idx += 2 # Consume the newline as well.
elsif @tokens[@idx] == "\n"
# ignore
@idx += 1
@@ -547,21 +574,22 @@ class Parser
@idx += 1
if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
# Zero operand instruction, and it's the last one.
- list << Instruction.new(codeOrigin, name, [])
+ list << Instruction.new(codeOrigin, name, [], @annotation)
+ @annotation = nil
break
- elsif isAnnotation @tokens[@idx]
- annotation = @tokens[@idx].string
- list << Instruction.new(codeOrigin, name, [], annotation)
+ elsif @tokens[@idx].is_a? Annotation
+ list << Instruction.new(codeOrigin, name, [], @tokens[@idx].string)
+ @annotation = nil
@idx += 2 # Consume the newline as well.
elsif @tokens[@idx] == "\n"
# Zero operand instruction.
- list << Instruction.new(codeOrigin, name, [])
+ list << Instruction.new(codeOrigin, name, [], @annotation)
+ @annotation = nil
@idx += 1
else
# It's definitely an instruction, and it has at least one operand.
operands = []
endOfSequence = false
- annotation = nil
loop {
operands << parseOperand("while inside of instruction #{name}")
if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
@@ -571,8 +599,8 @@ class Parser
elsif @tokens[@idx] == ","
# Has another operand.
@idx += 1
- elsif isAnnotation @tokens[@idx]
- annotation = @tokens[@idx].string
+ elsif @tokens[@idx].is_a? Annotation
+ @annotation = @tokens[@idx].string
@idx += 2 # Consume the newline as well.
break
elsif @tokens[@idx] == "\n"
@@ -583,11 +611,14 @@ class Parser
parseError("Expected a comma, newline, or #{final} after #{operands.last.dump}")
end
}
- list << Instruction.new(codeOrigin, name, operands, annotation)
+ list << Instruction.new(codeOrigin, name, operands, @annotation)
+ @annotation = nil
if endOfSequence
break
end
end
+
+ # Check for potential macro invocation:
elsif isIdentifier @tokens[@idx]
codeOrigin = @tokens[@idx].codeOrigin
name = @tokens[@idx].string
@@ -624,7 +655,13 @@ class Parser
end
}
end
- list << MacroCall.new(codeOrigin, name, operands)
+ # Check if there's a trailing annotation after the macro invoke:
+ if @tokens[@idx].is_a? Annotation
+ @annotation = @tokens[@idx].string
+ @idx += 2 # Consume the newline as well.
+ end
+ list << MacroCall.new(codeOrigin, name, operands, @annotation)
+ @annotation = nil
else
parseError "Expected \"(\" after #{name}"
end
diff --git a/Source/JavaScriptCore/offlineasm/transform.rb b/Source/JavaScriptCore/offlineasm/transform.rb
index a47ea0ad6..c838629f0 100644
--- a/Source/JavaScriptCore/offlineasm/transform.rb
+++ b/Source/JavaScriptCore/offlineasm/transform.rb
@@ -229,6 +229,9 @@ class Sequence
mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
end
}
+ if item.annotation
+ newList << Instruction.new(item.codeOrigin, "localAnnotation", [], item.annotation)
+ end
newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
else
newList << item.demacroify(myMacros)
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index 470318a09..cebc83326 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -624,8 +624,8 @@ class Instruction
end
def lowerX86Common
- $asm.codeOrigin codeOriginString
- $asm.annotation annotation
+ $asm.codeOrigin codeOriginString if $enableCodeOriginComments
+ $asm.annotation annotation if $enableInstrAnnotations
case opcode
when "addi"
@@ -1028,7 +1028,7 @@ class Instruction
when "leap"
$asm.puts "lea#{x86Suffix(:ptr)} #{operands[0].x86AddressOperand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
else
- raise "Bad opcode: #{opcode}"
+ lowerDefault
end
end
end
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index f81ae10f3..d3d0fe574 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -66,10 +66,6 @@
#include <unicode/udat.h>
#endif
-#if OS(WINCE) && !PLATFORM(QT)
-extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); //provided by libce
-#endif
-
using namespace WTF;
namespace JSC {
@@ -223,22 +219,57 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, doubl
static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format)
{
+#if OS(WINDOWS)
+ SYSTEMTIME systemTime;
+ memset(&systemTime, 0, sizeof(systemTime));
+ systemTime.wYear = gdt.year + 1900;
+ systemTime.wMonth = gdt.month + 1;
+ systemTime.wDay = gdt.monthDay;
+ systemTime.wDayOfWeek = gdt.weekDay;
+ systemTime.wHour = gdt.hour;
+ systemTime.wMinute = gdt.minute;
+ systemTime.wSecond = gdt.second;
+
+ Vector<UChar, 128> buffer;
+ size_t length = 0;
+
+ if (format == LocaleDate) {
+ buffer.resize(GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &systemTime, 0, 0, 0));
+ length = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &systemTime, 0, buffer.data(), buffer.size());
+ } else if (format == LocaleTime) {
+ buffer.resize(GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systemTime, 0, 0, 0));
+ length = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systemTime, 0, buffer.data(), buffer.size());
+ } else if (format == LocaleDateAndTime) {
+ buffer.resize(GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &systemTime, 0, 0, 0) + GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systemTime, 0, 0, 0));
+ length = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &systemTime, 0, buffer.data(), buffer.size());
+ if (length) {
+ buffer[length - 1] = ' ';
+ length += GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systemTime, 0, buffer.data() + length, buffer.size() - length);
+ }
+ } else
+ ASSERT_NOT_REACHED();
+
+ // Remove terminating null character.
+ if (length)
+ length--;
+
+ return jsNontrivialString(exec, UString(buffer.data(), length));
+
+#else // OS(WINDOWS)
+
#if HAVE(LANGINFO_H)
static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT };
-#elif (OS(WINCE) && !PLATFORM(QT))
- // strftime() does not support '#' on WinCE
- static const char* const formatStrings[] = { "%c", "%x", "%X" };
#else
static const char* const formatStrings[] = { "%#c", "%#x", "%X" };
#endif
-
+
// Offset year if needed
struct tm localTM = gdt;
int year = gdt.year + 1900;
bool yearNeedsOffset = year < 1900 || year > 2038;
if (yearNeedsOffset)
localTM.tm_year = equivalentYearForDST(year) - 1900;
-
+
#if HAVE(LANGINFO_H)
// We do not allow strftime to generate dates with 2-digits years,
// both to avoid ambiguity, and a crash in strncpy, for years that
@@ -259,19 +290,19 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L
#else
size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM);
#endif
-
+
if (ret == 0)
return jsEmptyString(exec);
-
+
// Copy original into the buffer
if (yearNeedsOffset && format != LocaleTime) {
static const int yearLen = 5; // FIXME will be a problem in the year 10,000
char yearString[yearLen];
-
+
snprintf(yearString, yearLen, "%d", localTM.tm_year + 1900);
char* yearLocation = strstr(timebuffer, yearString);
snprintf(yearString, yearLen, "%d", year);
-
+
strncpy(yearLocation, yearString, yearLen - 1);
}
@@ -296,6 +327,7 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L
#endif
return jsNontrivialString(exec, timebuffer);
+#endif // OS(WINDOWS)
}
static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double, LocaleDateTimeFormat format)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 90925778b..59a672f67 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -129,6 +129,10 @@ namespace JSC {
#if ENABLE(DFG_JIT)
class ConservativeRoots;
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
+#endif
struct ScratchBuffer {
ScratchBuffer()
: m_activeLength(0)
@@ -151,6 +155,9 @@ namespace JSC {
size_t m_activeLength;
void* m_buffer[0];
};
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
#endif
class JSGlobalData : public ThreadSafeRefCounted<JSGlobalData> {
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index ccc49fd5c..587929f66 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -599,19 +599,13 @@ PropertyStorage JSObject::growOutOfLineStorage(JSGlobalData& globalData, size_t
PropertyStorage oldPropertyStorage = m_outOfLineStorage.get();
PropertyStorage newPropertyStorage = 0;
- if (!oldPropertyStorage) {
- // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
- void* temp = newPropertyStorage;
- if (!globalData.heap.tryAllocateStorage(sizeof(WriteBarrierBase<Unknown>) * newSize, &temp))
- CRASH();
- newPropertyStorage = static_cast<PropertyStorage>(temp);
- } else {
- // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
- void* temp = oldPropertyStorage;
- if (!globalData.heap.tryReallocateStorage(&temp, sizeof(WriteBarrierBase<Unknown>) * oldSize, sizeof(WriteBarrierBase<Unknown>) * newSize))
- CRASH();
- newPropertyStorage = static_cast<PropertyStorage>(temp);
- }
+ // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
+ void* temp = newPropertyStorage;
+ if (!globalData.heap.tryAllocateStorage(sizeof(WriteBarrierBase<Unknown>) * newSize, &temp))
+ CRASH();
+ newPropertyStorage = static_cast<PropertyStorage>(temp);
+
+ memcpy(newPropertyStorage, oldPropertyStorage, sizeof(WriteBarrierBase<Unknown>) * oldSize);
ASSERT(newPropertyStorage);
return newPropertyStorage;
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index 509ff3d45..e02105826 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -259,8 +259,8 @@ void Structure::materializePropertyMap(JSGlobalData& globalData)
inline size_t nextOutOfLineStorageCapacity(size_t currentCapacity)
{
if (!currentCapacity)
- return 4;
- return currentCapacity * 2;
+ return initialOutOfLineCapacity;
+ return currentCapacity * outOfLineGrowthFactor;
}
void Structure::growOutOfLineCapacity()
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index d2d025b98..712ea6bb5 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -53,6 +53,15 @@ namespace JSC {
class SlotVisitor;
class JSString;
+ // The out-of-line property storage capacity to use when first allocating out-of-line
+ // storage. Note that all objects start out without having any out-of-line storage;
+ // this comes into play only on the first property store that exhausts inline storage.
+ static const unsigned initialOutOfLineCapacity = 4;
+
+ // The factor by which to grow out-of-line storage when it is exhausted, after the
+ // initial allocation.
+ static const unsigned outOfLineGrowthFactor = 2;
+
class Structure : public JSCell {
public:
friend class StructureTransitionTable;