summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-09-24 13:09:44 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-09-24 13:09:44 +0200
commitdc6262b587c71c14e30d93e57ed812e36a79a33e (patch)
tree03ff986e7aa38bba0c0ef374f44fda52aff93f01 /Source/JavaScriptCore
parent02e1fbbefd49229b102ef107bd70ce974a2d85fb (diff)
downloadqtwebkit-dc6262b587c71c14e30d93e57ed812e36a79a33e.tar.gz
Imported WebKit commit 6339232fec7f5d9984a33388aecfd2cbc7832053 (http://svn.webkit.org/repository/webkit/trunk@129343)
New snapshot with build fixes for latest qtbase
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.h2
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObjectFunctions.h2
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.cpp2
-rw-r--r--Source/JavaScriptCore/ChangeLog592
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig3
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig2
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def2
-rw-r--r--Source/JavaScriptCore/assembler/LinkBuffer.h3
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h6
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h7
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp16
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h48
-rw-r--r--Source/JavaScriptCore/bytecode/Opcode.h4
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp66
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h4
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp15
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp12
-rw-r--r--Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h19
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp27
-rw-r--r--Source/JavaScriptCore/dfg/DFGCSEPhase.cpp165
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h6
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h8
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeType.h9
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp5
-rw-r--r--Source/JavaScriptCore/dfg/DFGRepatch.cpp19
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp5
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp112
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp96
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp2
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp47
-rw-r--r--Source/JavaScriptCore/jit/JITCall.cpp10
-rw-r--r--Source/JavaScriptCore/jit/JITCall32_64.cpp10
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h1
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp27
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp27
-rw-r--r--Source/JavaScriptCore/jit/JITStubRoutine.h3
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp29
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h2
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp26
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm21
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm21
-rw-r--r--Source/JavaScriptCore/offlineasm/armv7.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/cloop.rb2
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp26
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h25
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConventions.h2
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp38
-rw-r--r--Source/JavaScriptCore/runtime/ArrayStorage.h10
-rw-r--r--Source/JavaScriptCore/runtime/ClassInfo.h6
-rw-r--r--Source/JavaScriptCore/runtime/CommonSlowPaths.h22
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h4
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h83
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h11
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp65
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h40
-rw-r--r--Source/JavaScriptCore/runtime/Options.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/SymbolTable.h16
-rw-r--r--Source/JavaScriptCore/tests/mozilla/expected.html14
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_2/function/function-001-n.js2
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_3/Script/function-001-n.js2
-rw-r--r--Source/JavaScriptCore/tests/mozilla/js1_3/regress/function-001-n.js2
72 files changed, 1346 insertions, 564 deletions
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.h b/Source/JavaScriptCore/API/JSCallbackObject.h
index 8d7aedd3e..5022aaf40 100644
--- a/Source/JavaScriptCore/API/JSCallbackObject.h
+++ b/Source/JavaScriptCore/API/JSCallbackObject.h
@@ -186,7 +186,7 @@ private:
static bool deleteProperty(JSCell*, ExecState*, PropertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
- static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);
+ static bool customHasInstance(JSObject*, ExecState*, JSValue);
static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
diff --git a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
index 39d078239..688e7b8b9 100644
--- a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -389,7 +389,7 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
}
template <class Parent>
-bool JSCallbackObject<Parent>::hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)
+bool JSCallbackObject<Parent>::customHasInstance(JSObject* object, ExecState* exec, JSValue value)
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(object);
JSContextRef execRef = toRef(exec);
diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp
index 4c986c253..bb92454bd 100644
--- a/Source/JavaScriptCore/API/JSValueRef.cpp
+++ b/Source/JavaScriptCore/API/JSValueRef.cpp
@@ -175,7 +175,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
JSObject* jsConstructor = toJS(constructor);
if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
return false;
- bool result = jsConstructor->methodTable()->hasInstance(jsConstructor, exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
+ bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index ca7100e21..5d81031ba 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,595 @@
+2012-09-23 Geoffrey Garen <ggaren@apple.com>
+
+ PutScopedVar should not be marked as clobbering the world
+ https://bugs.webkit.org/show_bug.cgi?id=97416
+
+ Reviewed by Filip Pizlo.
+
+ No performance change.
+
+ PutScopedVar doesn't have arbitrary side-effects, so it shouldn't be marked
+ as such.
+
+ * dfg/DFGNodeType.h:
+ (DFG):
+
+2012-09-23 Geoffrey Garen <ggaren@apple.com>
+
+ I accidentally the whole 32-bit :(.
+
+ Unbreak the DFG in 32-bit with the 32-bit path I forgot in my last patch.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-09-23 Byungwoo Lee <bw80.lee@gmail.com>
+
+ Fix build warnings : -Wunused-parameter, -Wparentheses, -Wuninitialized.
+ https://bugs.webkit.org/show_bug.cgi?id=97306
+
+ Reviewed by Benjamin Poulain.
+
+ Fix build warning about -Wunused-parameter on MachineStackMarker.cpp,
+ LLIntSlowPaths.cpp, DatePrototype.cpp, Options.cpp by using
+ UNUSED_PARAM() macro or remove parameter name.
+
+ * heap/MachineStackMarker.cpp:
+ (JSC::pthreadSignalHandlerSuspendResume):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::entryOSR):
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ * runtime/Options.cpp:
+ (JSC::computeNumberOfGCMarkers):
+
+2012-09-23 Gavin Barraclough <barraclough@apple.com>
+
+ Sorting a non-array creates propreties (spec-violation)
+ https://bugs.webkit.org/show_bug.cgi?id=25477
+
+ Reviewed by Oliver Hunt.
+
+ We're just calling get() to get properties, which is converting missing properties to
+ undefined. Hole values should be retained, and moved to the end of the array.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::getOrHole):
+ - Helper function, returns JSValue() instead of undefined for missing properties.
+ (JSC::arrayProtoFuncSort):
+ - Implemented per 15.4.4.11, see comments above.
+
+2012-09-23 Geoffrey Garen <ggaren@apple.com>
+
+ CSE for access to closure variables (get_/put_scoped_var)
+ https://bugs.webkit.org/show_bug.cgi?id=97414
+
+ Reviewed by Oliver Hunt.
+
+ I separated loading a scope from loading its storage pointer, so we can
+ CSE the storage pointer load. Then, I copied the global var CSE and adjusted
+ it for closure vars.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute): Renamed GetScopeChain => GetScope to
+ reflect renames from a few weeks ago.
+
+ Added a case for the storage pointer load, similar to object storage pointer load.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock): Added an independent node for
+ the storage pointer.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (CSEPhase):
+ (JSC::DFG::CSEPhase::scopedVarStoreElimination):
+ (JSC::DFG::CSEPhase::getScopeLoadElimination):
+ (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination):
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE): Copied globalVarLoad/StoreElimination
+ and adapted the same logic to closure vars.
+
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasScopeChainDepth):
+ (JSC::DFG::Node::scope):
+ (Node):
+ * dfg/DFGNodeType.h:
+ (DFG): GetScopedVar and GetGlobalVar are no longer MustGenerate. I'm not
+ sure why they ever were. But these are simple load operations so, if they're
+ unused, they're truly dead.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Updated for renames and split-out
+ node for getting the storage pointer.
+
+2012-09-21 Geoffrey Garen <ggaren@apple.com>
+
+ Unreviewed, rolled out a line I committed by accident.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+
+2012-09-21 Geoffrey Garen <ggaren@apple.com>
+
+ Optimized closures that capture arguments
+ https://bugs.webkit.org/show_bug.cgi?id=97358
+
+ Reviewed by Oliver Hunt.
+
+ Previously, the activation object was responsible for capturing all
+ arguments in a way that was convenient for the arguments object. Now,
+ we move all captured variables into a contiguous region in the stack,
+ allocate an activation for exactly that size, and make the arguments
+ object responsible for knowing all the places to which arguments could
+ have moved.
+
+ This seems like the right tradeoff because
+
+ (a) Closures are common and long-lived, so we want them to be small.
+
+ (b) Our primary strategy for optimizing the arguments object is to make
+ it go away. If you're allocating arguments objects, you're already having
+ a bad time.
+
+ (c) It's common to use either the arguments object or named argument
+ closure, but not both.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::argumentsRegister):
+ (JSC::CodeBlock::activationRegister):
+ (JSC::CodeBlock::isCaptured):
+ (JSC::CodeBlock::argumentIndexAfterCapture): m_numCapturedVars is gone
+ now -- we have an explicit range instead.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): Move captured arguments
+ into the captured region of local variables for space efficiency. Record
+ precise data about where they moved for the sake of the arguments object.
+
+ Some of this data was previously wrong, but it didn't cause any problems
+ because the arguments weren't actually moving.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::flushArgumentsAndCapturedVariables): Don't
+ assume that captured vars are in any particular location -- always ask
+ the CodeBlock. This is better encapsulation.
+
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): I rename things sometimes.
+
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::tearOff): Account for a particularly nasty edge case.
+
+ (JSC::Arguments::didTearOffActivation): Don't allocate our slow arguments
+ data on tear-off. We need to allocate it eagerly instead, since we need
+ to know about displaced, captured arguments during access before tear-off.
+
+ * runtime/Arguments.h:
+ (JSC::Arguments::allocateSlowArguments):
+ (JSC::Arguments::argument): Tell our slow arguments array where all arguments
+ are, even if they are not captured. This simplifies some things, so we don't
+ have to account explicitly for the full matrix of (not torn off, torn off)
+ * (captured, not captured).
+
+ (JSC::Arguments::finishCreation): Allocate our slow arguments array eagerly
+ because we need to know about displaced, captured arguments during access
+ before tear-off.
+
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ * runtime/Executable.h:
+ (JSC::FunctionExecutable::parameterCount):
+ (FunctionExecutable):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::visitChildren):
+ * runtime/JSActivation.h:
+ (JSActivation):
+ (JSC::JSActivation::create):
+ (JSC::JSActivation::JSActivation):
+ (JSC::JSActivation::registerOffset):
+ (JSC::JSActivation::tearOff):
+ (JSC::JSActivation::allocationSize):
+ (JSC::JSActivation::isValid): This is really the point of the patch. All
+ the pointer math in Activations basically boils away, since we always
+ copy a contiguous region of captured variables now.
+
+ * runtime/SymbolTable.h:
+ (JSC::SlowArgument::SlowArgument):
+ (SlowArgument):
+ (SharedSymbolTable):
+ (JSC::SharedSymbolTable::captureCount):
+ (JSC::SharedSymbolTable::SharedSymbolTable): AllOfTheThings capture mode
+ is gone now -- that's the point of the patch. indexIfCaptured gets renamed
+ to index because we always have an index, even if not captured. (The only
+ time when the index is meaningless is when we're Deleted.)
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ Eeeep - broke early boyer in bug#97382
+ https://bugs.webkit.org/show_bug.cgi?id=97383
+
+ Rubber stamped by Sam Weinig.
+
+ missed a child3 -> child2!
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ Unreviewed windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ Pedantic test in Mozilla's JavaScript test suite fails. function-001.js function-001-n.js
+ https://bugs.webkit.org/show_bug.cgi?id=27219
+
+ Reviewed by Sam Weinig.
+
+ These tests are just wrong.
+ See ECMA 262 A.5, FunctionDelcaration does not require a semicolon.
+
+ * tests/mozilla/expected.html:
+ * tests/mozilla/js1_2/function/function-001-n.js:
+ * tests/mozilla/js1_3/Script/function-001-n.js:
+ * tests/mozilla/js1_3/regress/function-001-n.js:
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ Remove redundant argument to op_instanceof
+ https://bugs.webkit.org/show_bug.cgi?id=97382
+
+ Reviewed by Geoff Garen.
+
+ No longer needed after my last change.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitInstanceOf):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::InstanceOfNode::emitBytecode):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ Unreviewed windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ instanceof should not get the prototype for non-default HasInstance
+ https://bugs.webkit.org/show_bug.cgi?id=68656
+
+ Reviewed by Oliver Hunt.
+
+ Instanceof is currently implemented as a sequance of three opcodes:
+ check_has_instance
+ get_by_id(prototype)
+ op_instanceof
+ There are three interesting types of base value that instanceof can be applied to:
+ (A) Objects supporting default instanceof behaviour (functions, other than those created with bind)
+ (B) Objects overriding the default instancecof behaviour with a custom one (API objects, bound functions)
+ (C) Values that do not respond to the [[HasInstance]] trap.
+ Currently check_has_instance handles case (C), leaving the op_instanceof opcode to handle (A) & (B). There are
+ two problems with this apporach. Firstly, this is suboptimal for case (A), since we have to check for
+ hasInstance support twice (once in check_has_instance, then for default behaviour in op_instanceof). Secondly,
+ this means that in cases (B) we also perform the get_by_id, which is both suboptimal and an observable spec
+ violation.
+
+ The fix here is to move handing of non-default instanceof (cases (B)) to the check_has_instance op, leaving
+ op_instanceof to handle only cases (A).
+
+ * API/JSCallbackObject.h:
+ (JSCallbackObject):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::customHasInstance):
+ * API/JSValueRef.cpp:
+ (JSValueIsInstanceOfConstructor):
+ - renamed hasInstance to customHasInstance
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ - added additional parameters to check_has_instance opcode
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ - added additional parameters to check_has_instance opcode
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitCheckHasInstance):
+ - added additional parameters to check_has_instance opcode
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ - added additional parameters to check_has_instance opcode
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::InstanceOfNode::emitBytecode):
+ - added additional parameters to check_has_instance opcode
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ - added additional parameters to check_has_instance opcode
+ * interpreter/Interpreter.cpp:
+ (JSC::isInvalidParamForIn):
+ (JSC::Interpreter::privateExecute):
+ - Add handling for non-default instanceof to op_check_has_instance
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitArrayProfilingSiteForBytecodeIndex):
+ - Fixed no-LLInt no_DFG build
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_check_has_instance):
+ (JSC::JIT::emitSlow_op_check_has_instance):
+ - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance.
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof):
+ - no need to check for ImplementsDefaultHasInstance.
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_check_has_instance):
+ (JSC::JIT::emitSlow_op_check_has_instance):
+ - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance.
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof):
+ - no need to check for ImplementsDefaultHasInstance.
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ - Add handling for non-default instanceof to op_check_has_instance
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ - move check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance.
+ * runtime/ClassInfo.h:
+ (MethodTable):
+ (JSC):
+ - renamed hasInstance to customHasInstance
+ * runtime/CommonSlowPaths.h:
+ (CommonSlowPaths):
+ - removed opInstanceOfSlow (this was whittled down to one function call!)
+ * runtime/JSBoundFunction.cpp:
+ (JSC::JSBoundFunction::customHasInstance):
+ * runtime/JSBoundFunction.h:
+ (JSBoundFunction):
+ - renamed hasInstance to customHasInstance, reimplemented.
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::customHasInstance):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::hasInstance):
+ (JSC):
+ (JSC::JSObject::defaultHasInstance):
+ * runtime/JSObject.h:
+ (JSObject):
+
+2012-09-21 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix ARM build.
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::store8):
+ (MacroAssemblerARMv7):
+ * offlineasm/armv7.rb:
+
+2012-09-21 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION (r128400): Opening Google Web Fonts page hangs or crashes
+ https://bugs.webkit.org/show_bug.cgi?id=97328
+
+ Reviewed by Mark Hahnenberg.
+
+ It's a bad idea to emit stub code that reallocates property storage when we're in indexed
+ storage mode. DFGRepatch.cpp knew this and had the appropriate check in one of the places,
+ but it didn't have it in all of the places.
+
+ This change also adds some more handy disassembly support, which I used to find the bug.
+
+ * assembler/LinkBuffer.h:
+ (JSC):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::generateProtoChainAccessStub):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDList):
+ (JSC::DFG::emitPutReplaceStub):
+ (JSC::DFG::emitPutTransitionStub):
+ (JSC::DFG::tryCachePutByID):
+ * jit/JITStubRoutine.h:
+ (JSC):
+
+2012-09-21 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CSE assumes that a holy PutByVal does not interfere with GetArrayLength, when it clearly does
+ https://bugs.webkit.org/show_bug.cgi?id=97373
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::getArrayLengthElimination):
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGGraph.h:
+ (Graph):
+
+2012-09-21 Chris Rogers <crogers@google.com>
+
+ Add Web Audio support for deprecated/legacy APIs
+ https://bugs.webkit.org/show_bug.cgi?id=97050
+
+ Reviewed by Eric Carlson.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-09-21 Gavin Barraclough <barraclough@apple.com>
+
+ Global Math object should be configurable but isn't
+ https://bugs.webkit.org/show_bug.cgi?id=55343
+
+ Reviewed by Oliver Hunt.
+
+ This has no performance impact.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ - Make 'Math' a regular property.
+
+2012-09-21 Chao-ying Fu <fu@mips.com>
+
+ Add MIPS or32 function
+ https://bugs.webkit.org/show_bug.cgi?id=97157
+
+ Reviewed by Gavin Barraclough.
+
+ Add a missing or32 function.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::or32): New function.
+ (MacroAssemblerMIPS):
+
+2012-09-20 Filip Pizlo <fpizlo@apple.com>
+
+ CHECK_ARRAY_CONSISTENCY isn't being used or tested, so we should remove it
+ https://bugs.webkit.org/show_bug.cgi?id=97260
+
+ Rubber stamped by Geoffrey Garen.
+
+ Supporting it will become difficult as we add more indexing types. It makes more
+ sense to kill, especially since we don't appear to use it or test it, ever.
+
+ * runtime/ArrayConventions.h:
+ (JSC):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSplice):
+ * runtime/ArrayStorage.h:
+ (JSC::ArrayStorage::copyHeaderFromDuringGC):
+ (ArrayStorage):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncBind):
+ * runtime/JSArray.cpp:
+ (JSC::createArrayButterflyInDictionaryIndexingMode):
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::pop):
+ (JSC::JSArray::push):
+ (JSC::JSArray::sortNumeric):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::compactForSorting):
+ * runtime/JSArray.h:
+ (JSArray):
+ (JSC::createArrayButterfly):
+ (JSC::JSArray::tryCreateUninitialized):
+ (JSC::constructArray):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::createArrayStorage):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC):
+ * runtime/JSObject.h:
+ (JSC::JSObject::initializeIndex):
+ (JSObject):
+
+2012-09-20 Mark Lam <mark.lam@apple.com>
+
+ Fixed a missing semicolon in the C++ llint backend.
+ https://bugs.webkit.org/show_bug.cgi?id=97252.
+
+ Reviewed by Geoff Garen.
+
+ * offlineasm/cloop.rb:
+
+2012-09-20 Geoffrey Garen <ggaren@apple.com>
+
+ Refactored the interpreter and JIT so they don't dictate closure layout
+ https://bugs.webkit.org/show_bug.cgi?id=97221
+
+ Reviewed by Oliver Hunt.
+
+ Capture may change the location of an argument for space efficiency. This
+ patch removes static assumptions about argument location from the interpreter
+ and JIT.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::argumentIndexAfterCapture):
+ (JSC::ExecState::argumentAfterCapture): Factored out a helper function
+ so the compiler could share this logic.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BracketAccessorNode::emitBytecode): Don't emit optimized bracket
+ access on arguments if a parameter has been captured by name. This case is
+ rare and, where I've seen it in the wild, the optimization mostly failed
+ anyway due to arguments escape, so I didn't feel like writing and testing
+ five copies of the code that would handle it in the baseline engines.
+
+ The DFG can still synthesize this optimization even if we don't emit the
+ optimized bytecode for it.
+
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::symbolTableFor):
+ (AssemblyHelpers): Use the right helper function to account for the fact
+ that a parameter may have been captured by name and moved.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock): ASSERT that we haven't inlined
+ a .apply on captured arguments. Once we do start inlining such things,
+ we'll need to do a little bit of math here to get them right.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Added support for bracket access on
+ an arguments object where arguments have also been captured by name. We
+ load the true index of the argument from a side vector. Arguments elision
+ is very powerful in the DFG, so I wanted to keep it working, even in this
+ rare case.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::loadVarargs): Use the right helper function to account for the fact
+ that a parameter may have been captured by name and moved.
+
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileLoadVarargs): Don't use the inline copy loop if some
+ of our arguments have moved, since it would copy stale values. (We still
+ optimize the actual call, and elide the arguments object.)
+
2012-09-20 Gabor Rapcsanyi <rgabor@webkit.org>
[Qt] r129045 broke the ARM build
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index ec35cf673..1b4a75243 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -96,6 +96,7 @@ ENABLE_LEGACY_NOTIFICATIONS_macosx_1070 = ;
ENABLE_LEGACY_NOTIFICATIONS_macosx_1080 = ENABLE_LEGACY_NOTIFICATIONS;
ENABLE_LEGACY_NOTIFICATIONS_macosx_1090 = ENABLE_LEGACY_NOTIFICATIONS;
ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
+ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
ENABLE_LINK_PREFETCH = ;
ENABLE_LINK_PRERENDER = ;
ENABLE_MATHML = ENABLE_MATHML;
@@ -140,4 +141,4 @@ ENABLE_WIDGET_REGION_macosx = ENABLE_WIDGET_REGION;
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_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_TEXT_DECORATION) $(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_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(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_LEGACY_VENDOR_PREFIXES) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(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_WIDGET_REGION) $(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_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_TEXT_DECORATION) $(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_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(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_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(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_WIDGET_REGION) $(ENABLE_WORKERS) $(ENABLE_XSLT);
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index 83578f9e9..ffba40115 100644
--- a/Source/JavaScriptCore/Configurations/Version.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 537;
-MINOR_VERSION = 11;
+MINOR_VERSION = 12;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 4d54364f0..f7c0457bf 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -135,6 +135,7 @@ EXPORTS
?cryptographicallyRandomValues@WTF@@YAXPAXI@Z
?currentThread@WTF@@YAIXZ
?currentTime@WTF@@YANXZ
+ ?customHasInstance@JSCell@JSC@@KA_NPAVJSObject@2@PAVExecState@2@VJSValue@2@@Z
?data@CString@WTF@@QBEPBDXZ
?dataLog@WTF@@YAXPBDZZ
?dateToDaysFrom1970@WTF@@YANHHH@Z
@@ -222,7 +223,6 @@ EXPORTS
?globalObjectCount@Heap@JSC@@QAEIXZ
?grow@HandleSet@JSC@@AAEXXZ
?growOutOfLineStorage@JSObject@JSC@@QAEPAVButterfly@2@AAVJSGlobalData@2@II@Z
- ?hasInstance@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VJSValue@2@2@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@VPropertyName@2@@Z
?hashSlowCase@StringImpl@WTF@@ABEIXZ
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index 484d3a73f..770144d64 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -287,6 +287,9 @@ private:
#define FINALIZE_CODE(linkBufferReference, dataLogArgumentsForHeading) \
FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, dataLogArgumentsForHeading)
+#define FINALIZE_DFG_CODE(linkBufferReference, dataLogArgumentsForHeading) \
+ FINALIZE_CODE_IF(Options::showDFGDisassembly(), linkBufferReference, dataLogArgumentsForHeading)
+
} // namespace JSC
#endif // ENABLE(ASSEMBLER)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 09a88fdda..46d7225d0 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -743,6 +743,12 @@ public:
store8(src, ArmAddress(addressTempRegister, 0));
}
+ void store8(TrustedImm32 imm, void* address)
+ {
+ move(imm, dataTempRegister);
+ store8(dataTempRegister, address);
+ }
+
void store16(RegisterID src, BaseIndex address)
{
store16(src, setupArmAddress(address));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 8b3ce9f03..b3afae8df 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -335,6 +335,13 @@ public:
m_assembler.orInsn(dest, dest, dataTempRegister);
}
+ void or32(RegisterID src, AbsoluteAddress dest)
+ {
+ load32(dest.m_ptr, dataTempRegister);
+ m_assembler.orInsn(dataTempRegister, dataTempRegister, src);
+ store32(dataTempRegister, dest.m_ptr);
+ }
+
void rshift32(RegisterID shiftAmount, RegisterID dest)
{
m_assembler.srav(dest, dest, shiftAmount);
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 6b31be221..54dccb9ed 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -532,8 +532,8 @@ void CodeBlock::dump(ExecState* exec)
static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
this, codeTypeToString(codeType()), m_numParameters, m_numCalleeRegisters,
m_numVars);
- if (m_numCapturedVars)
- dataLog("; %d captured var(s)", m_numCapturedVars);
+ if (m_symbolTable->captureCount())
+ dataLog("; %d captured var(s)", m_symbolTable->captureCount());
if (usesArguments()) {
dataLog(
"; uses arguments, in r%d, r%d",
@@ -873,8 +873,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
break;
}
case op_check_has_instance: {
- int base = (++it)->u.operand;
- dataLog("[%4d] check_has_instance\t\t %s", location, registerName(exec, base).data());
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int r2 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ dataLog("[%4d] check_has_instance\t\t %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), offset, location + offset);
dumpBytecodeCommentAndNewLine(location);
break;
}
@@ -882,8 +885,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- int r3 = (++it)->u.operand;
- dataLog("[%4d] instanceof\t\t %s, %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data());
+ dataLog("[%4d] instanceof\t\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
dumpBytecodeCommentAndNewLine(location);
break;
}
@@ -1707,7 +1709,6 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
, m_heap(other.m_heap)
, m_numCalleeRegisters(other.m_numCalleeRegisters)
, m_numVars(other.m_numVars)
- , m_numCapturedVars(other.m_numCapturedVars)
, m_isConstructor(other.m_isConstructor)
, m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
, m_globalData(other.m_globalData)
@@ -1773,7 +1774,6 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo
, m_heap(&m_globalObject->globalData().heap)
, m_numCalleeRegisters(0)
, m_numVars(0)
- , m_numCapturedVars(0)
, m_isConstructor(isConstructor)
, m_numParameters(0)
, m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index d0c969c6d..22c48311c 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -432,6 +432,8 @@ namespace JSC {
unsigned instructionCount() { return m_instructions.size(); }
+ int argumentIndexAfterCapture(size_t argument);
+
#if ENABLE(JIT)
void setJITCode(const JITCode& code, MacroAssemblerCodePtr codeWithArityCheck)
{
@@ -514,7 +516,7 @@ namespace JSC {
m_argumentsRegister = argumentsRegister;
ASSERT(usesArguments());
}
- int argumentsRegister()
+ int argumentsRegister() const
{
ASSERT(usesArguments());
return m_argumentsRegister;
@@ -529,7 +531,7 @@ namespace JSC {
{
m_activationRegister = activationRegister;
}
- int activationRegister()
+ int activationRegister() const
{
ASSERT(needsFullScopeChain());
return m_activationRegister;
@@ -552,11 +554,24 @@ namespace JSC {
if (inlineCallFrame && !operandIsArgument(operand))
return inlineCallFrame->capturedVars.get(operand);
- // Our estimate of argument capture is conservative.
if (operandIsArgument(operand))
- return needsActivation() || usesArguments();
+ return usesArguments();
+
+ // The activation object isn't in the captured region, but it's "captured"
+ // in the sense that stores to its location can be observed indirectly.
+ if (needsActivation() && operand == activationRegister())
+ return true;
+
+ // Ditto for the arguments object.
+ if (usesArguments() && operand == argumentsRegister())
+ return true;
- return operand < m_numCapturedVars;
+ // Ditto for the arguments object.
+ if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
+ return true;
+
+ return operand >= m_symbolTable->captureStart()
+ && operand < m_symbolTable->captureEnd();
}
CodeType codeType() const { return m_codeType; }
@@ -1174,7 +1189,6 @@ namespace JSC {
int m_numCalleeRegisters;
int m_numVars;
- int m_numCapturedVars;
bool m_isConstructor;
protected:
@@ -1520,6 +1534,18 @@ namespace JSC {
return baselineCodeBlock;
}
+ inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
+ {
+ if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
+ return CallFrame::argumentOffset(argument);
+
+ const SlowArgument* slowArguments = symbolTable()->slowArguments();
+ if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
+ return CallFrame::argumentOffset(argument);
+
+ ASSERT(slowArguments[argument].status == SlowArgument::Captured);
+ return slowArguments[argument].index;
+ }
inline Register& ExecState::r(int index)
{
@@ -1552,15 +1578,7 @@ namespace JSC {
if (!codeBlock())
return this[argumentOffset(argument)].jsValue();
- if (argument >= static_cast<size_t>(codeBlock()->symbolTable()->parameterCount()))
- return this[argumentOffset(argument)].jsValue();
-
- const SlowArgument* slowArguments = codeBlock()->symbolTable()->slowArguments();
- if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
- return this[argumentOffset(argument)].jsValue();
-
- ASSERT(slowArguments[argument].status == SlowArgument::Captured);
- return this[slowArguments[argument].indexIfCaptured].jsValue();
+ return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
}
#if ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index 87b100056..a5d466154 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -84,8 +84,8 @@ namespace JSC {
macro(op_bitxor, 5) \
macro(op_bitor, 5) \
\
- macro(op_check_has_instance, 2) \
- macro(op_instanceof, 5) \
+ macro(op_check_has_instance, 5) \
+ macro(op_instanceof, 4) \
macro(op_typeof, 3) \
macro(op_is_undefined, 3) \
macro(op_is_boolean, 3) \
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index e7a80fe2c..13a2defff 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -304,8 +304,6 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, JSScope* scope, S
// FIXME: Move code that modifies the global object to Interpreter::execute.
- codeBlock->m_numCapturedVars = codeBlock->m_numVars;
-
if (compilationKind == OptimizingCompilation)
return;
@@ -392,6 +390,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
m_codeBlock->setActivationRegister(m_activationRegister->index());
}
+ symbolTable->setCaptureStart(m_codeBlock->m_numVars);
+
if (functionBody->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks) { // May reify arguments object.
RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'.
@@ -423,32 +423,33 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
}
}
- bool mayReifyArgumentsObject = codeBlock->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks;
+ bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
+
bool capturesAnyArgumentByName = false;
- if (functionBody->hasCapturedVariables()) {
+ Vector<RegisterID*> capturedArguments;
+ if (functionBody->hasCapturedVariables() || shouldCaptureAllTheThings) {
FunctionParameters& parameters = *functionBody->parameters();
+ capturedArguments.resize(parameters.size());
for (size_t i = 0; i < parameters.size(); ++i) {
- if (!functionBody->captures(parameters[i]))
+ capturedArguments[i] = 0;
+ if (!functionBody->captures(parameters[i]) && !shouldCaptureAllTheThings)
continue;
capturesAnyArgumentByName = true;
- break;
+ capturedArguments[i] = addVar();
}
}
- if (mayReifyArgumentsObject || capturesAnyArgumentByName) {
- symbolTable->setCaptureMode(SharedSymbolTable::AllOfTheThings);
- symbolTable->setCaptureStart(-CallFrame::offsetFor(symbolTable->parameterCountIncludingThis()));
- } else {
- symbolTable->setCaptureMode(SharedSymbolTable::SomeOfTheThings);
- symbolTable->setCaptureStart(m_codeBlock->m_numVars);
- }
-
- if (mayReifyArgumentsObject && capturesAnyArgumentByName) {
+ if (capturesAnyArgumentByName && !codeBlock->isStrictMode()) {
size_t parameterCount = symbolTable->parameterCount();
OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]);
for (size_t i = 0; i < parameterCount; ++i) {
+ if (!capturedArguments[i]) {
+ ASSERT(slowArguments[i].status == SlowArgument::Normal);
+ slowArguments[i].index = CallFrame::argumentOffset(i);
+ continue;
+ }
slowArguments[i].status = SlowArgument::Captured;
- slowArguments[i].indexIfCaptured = CallFrame::argumentOffset(i);
+ slowArguments[i].index = capturedArguments[i]->index();
}
symbolTable->setSlowArguments(slowArguments.release());
}
@@ -491,7 +492,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
instructions().append(m_activationRegister->index());
}
- codeBlock->m_numCapturedVars = codeBlock->m_numVars;
+ symbolTable->setCaptureEnd(codeBlock->m_numVars);
m_firstLazyFunction = codeBlock->m_numVars;
for (size_t i = 0; i < functionStack.size(); ++i) {
@@ -518,10 +519,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
}
- if (m_shouldEmitDebugHooks || codeBlock->usesEval())
- codeBlock->m_numCapturedVars = codeBlock->m_numVars;
-
- symbolTable->setCaptureEnd(codeBlock->m_numCapturedVars);
+ if (shouldCaptureAllTheThings)
+ symbolTable->setCaptureEnd(codeBlock->m_numVars);
FunctionParameters& parameters = *functionBody->parameters();
m_parameters.grow(parameters.size() + 1); // reserve space for "this"
@@ -531,9 +530,16 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
m_thisRegister.setIndex(nextParameterIndex--);
m_codeBlock->addParameter();
- for (size_t i = 0; i < parameters.size(); ++i)
- addParameter(parameters[i], nextParameterIndex--);
-
+ for (size_t i = 0; i < parameters.size(); ++i, --nextParameterIndex) {
+ int index = nextParameterIndex;
+ if (capturedArguments.size() && capturedArguments[i]) {
+ ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters[i])) || shouldCaptureAllTheThings);
+ index = capturedArguments[i]->index();
+ RegisterID original(nextParameterIndex);
+ emitMove(capturedArguments[i], &original);
+ }
+ addParameter(parameters[i], index);
+ }
preserveLastVar();
// We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
@@ -603,7 +609,6 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, JSScope* scope, SharedS
for (size_t i = 0; i < numVariables; ++i)
variables.append(*varStack[i].first);
codeBlock->adoptVariables(variables);
- codeBlock->m_numCapturedVars = codeBlock->m_numVars;
preserveLastVar();
}
@@ -1457,18 +1462,21 @@ ResolveResult BytecodeGenerator::resolveConstDecl(const Identifier& property)
return ResolveResult::dynamicResolve(scopeDepth());
}
-void BytecodeGenerator::emitCheckHasInstance(RegisterID* base)
-{
+void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
+{
+ size_t begin = instructions().size();
emitOpcode(op_check_has_instance);
+ instructions().append(dst->index());
+ instructions().append(value->index());
instructions().append(base->index());
+ instructions().append(target->bind(begin, instructions().size()));
}
-RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
+RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
{
emitOpcode(op_instanceof);
instructions().append(dst->index());
instructions().append(value->index());
- instructions().append(base->index());
instructions().append(basePrototype->index());
return dst;
}
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 398719749..1bf1d8f26 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -455,8 +455,8 @@ namespace JSC {
RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
- void emitCheckHasInstance(RegisterID* base);
- RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype);
+ void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target);
+ RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index e4d35471f..823dadf14 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -320,7 +320,9 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe
RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_base->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())) {
+ if (m_base->isResolveNode()
+ && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())
+ && !generator.symbolTable().slowArguments()) {
RegisterID* property = generator.emitNode(m_subscript);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
@@ -1086,15 +1088,20 @@ RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterI
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
+ RefPtr<RegisterID> prototype = generator.newTemporary();
+ RefPtr<RegisterID> dstReg = generator.finalDestination(dst, src1.get());
+ RefPtr<Label> target = generator.newLabel();
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitCheckHasInstance(src2.get());
+ generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get());
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
+ generator.emitGetById(prototype.get(), src2.get(), generator.globalData()->propertyNames->prototype);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
+ RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), prototype.get());
+ generator.emitLabel(target.get());
+ return result;
}
// ------------------------------ LogicalOpNode ----------------------------
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 50b9e2b9f..18b5ad02a 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -1262,11 +1262,17 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(nodeIndex).set(SpecFunction);
break;
- case GetScopeChain:
+ case GetScope:
node.setCanExit(false);
forNode(nodeIndex).set(SpecCellOther);
break;
-
+
+ case GetScopeRegisters:
+ node.setCanExit(false);
+ forNode(node.child1()).filter(SpecCell);
+ forNode(nodeIndex).clear(); // The result is not a JS value.
+ break;
+
case GetScopedVar:
node.setCanExit(false);
forNode(nodeIndex).makeTop();
@@ -1477,7 +1483,7 @@ bool AbstractState::execute(unsigned indexInBlock)
// Again, sadly, we don't propagate the fact that we've done InstanceOf
if (!(m_graph[node.child1()].prediction() & ~SpecCell) && !(forNode(node.child1()).m_type & ~SpecCell))
forNode(node.child1()).filter(SpecCell);
- forNode(node.child3()).filter(SpecCell);
+ forNode(node.child2()).filter(SpecCell);
forNode(nodeIndex).set(SpecBoolean);
break;
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
index ba6673963..513357424 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
@@ -584,8 +584,8 @@ public:
node.convertToGetLocalUnlinked(
static_cast<VirtualRegister>(
node.codeOrigin.inlineCallFrame->stackOffset +
- argumentToOperand(index + 1)));
-
+ m_graph.baselineCodeBlockFor(node.codeOrigin)->argumentIndexAfterCapture(index)));
+
NodeIndex checkNodeIndex = m_graph.size();
m_graph.append(check);
insertionSet.append(indexInBlock, checkNodeIndex);
diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
index 57f758c9c..a2003c5bf 100644
--- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
+++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
@@ -343,6 +343,25 @@ public:
return argumentsRegisterFor(codeOrigin.inlineCallFrame);
}
+ SharedSymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
+ {
+ return baselineCodeBlockFor(codeOrigin)->symbolTable();
+ }
+
+ int offsetOfLocals(const CodeOrigin& codeOrigin)
+ {
+ if (!codeOrigin.inlineCallFrame)
+ return 0;
+ return codeOrigin.inlineCallFrame->stackOffset * sizeof(Register);
+ }
+
+ int offsetOfArgumentsIncludingThis(const CodeOrigin& codeOrigin)
+ {
+ if (!codeOrigin.inlineCallFrame)
+ return CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register);
+ return (codeOrigin.inlineCallFrame->stackOffset + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register);
+ }
+
Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
static const double twoToThe32;
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index fb897ff5b..901b67b19 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -467,8 +467,11 @@ private:
numArguments = m_inlineStackTop->m_codeBlock->numParameters();
for (unsigned argument = numArguments; argument-- > 1;)
flush(argumentToOperand(argument));
- for (unsigned local = m_inlineStackTop->m_codeBlock->m_numCapturedVars; local--;)
+ for (int local = 0; local < m_inlineStackTop->m_codeBlock->m_numVars; ++local) {
+ if (!m_inlineStackTop->m_codeBlock->isCaptured(local))
+ continue;
flush(local);
+ }
}
// Get an operand, and perform a ToInt32/ToNumber conversion on it.
@@ -2049,14 +2052,13 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_check_has_instance:
- addToGraph(CheckHasInstance, get(currentInstruction[1].u.operand));
+ addToGraph(CheckHasInstance, get(currentInstruction[3].u.operand));
NEXT_OPCODE(op_check_has_instance);
case op_instanceof: {
NodeIndex value = get(currentInstruction[2].u.operand);
- NodeIndex baseValue = get(currentInstruction[3].u.operand);
- NodeIndex prototype = get(currentInstruction[4].u.operand);
- set(currentInstruction[1].u.operand, addToGraph(InstanceOf, value, baseValue, prototype));
+ NodeIndex prototype = get(currentInstruction[3].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(InstanceOf, value, prototype));
NEXT_OPCODE(op_instanceof);
}
@@ -2263,8 +2265,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
int dst = currentInstruction[1].u.operand;
int slot = currentInstruction[2].u.operand;
int depth = currentInstruction[3].u.operand;
- NodeIndex getScopeChain = addToGraph(GetScopeChain, OpInfo(depth));
- NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo(prediction), getScopeChain);
+ NodeIndex getScope = addToGraph(GetScope, OpInfo(depth));
+ NodeIndex getScopeRegisters = addToGraph(GetScopeRegisters, getScope);
+ NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo(prediction), getScopeRegisters);
set(dst, getScopedVar);
NEXT_OPCODE(op_get_scoped_var);
}
@@ -2272,8 +2275,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
int slot = currentInstruction[1].u.operand;
int depth = currentInstruction[2].u.operand;
int source = currentInstruction[3].u.operand;
- NodeIndex getScopeChain = addToGraph(GetScopeChain, OpInfo(depth));
- addToGraph(PutScopedVar, OpInfo(slot), getScopeChain, get(source));
+ NodeIndex getScope = addToGraph(GetScope, OpInfo(depth));
+ NodeIndex getScopeRegisters = addToGraph(GetScopeRegisters, getScope);
+ addToGraph(PutScopedVar, OpInfo(slot), getScope, getScopeRegisters, get(source));
NEXT_OPCODE(op_put_scoped_var);
}
case op_get_by_id:
@@ -2714,6 +2718,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_call_varargs: {
ASSERT(m_inlineStackTop->m_inlineCallFrame);
ASSERT(currentInstruction[3].u.operand == m_inlineStackTop->m_codeBlock->argumentsRegister());
+ ASSERT(!m_inlineStackTop->m_codeBlock->symbolTable()->slowArguments());
// It would be cool to funnel this into handleCall() so that it can handle
// inlining. But currently that won't be profitable anyway, since none of the
// uses of call_varargs will be inlineable. So we set this up manually and
@@ -3282,10 +3287,10 @@ void ByteCodeParser::parseCodeBlock()
CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("Parsing code block %p. codeType = %s, numCapturedVars = %u, needsFullScopeChain = %s, needsActivation = %s, isStrictMode = %s\n",
+ dataLog("Parsing code block %p. codeType = %s, captureCount = %u, needsFullScopeChain = %s, needsActivation = %s, isStrictMode = %s\n",
codeBlock,
codeTypeToString(codeBlock->codeType()),
- codeBlock->m_numCapturedVars,
+ codeBlock->symbolTable()->captureCount(),
codeBlock->needsFullScopeChain()?"true":"false",
codeBlock->ownerExecutable()->needsActivation()?"true":"false",
codeBlock->ownerExecutable()->isStrictMode()?"true":"false");
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 111c15f17..cea2f3c48 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -96,6 +96,9 @@ private:
break;
Node& otherNode = m_graph[index];
+ if (!otherNode.shouldGenerate())
+ continue;
+
if (node.op() != otherNode.op())
continue;
@@ -157,38 +160,34 @@ private:
return NoNode;
}
- NodeIndex impureCSE(Node& node)
+ NodeIndex getArrayLengthElimination(NodeIndex array)
{
- NodeIndex child1 = canonicalize(node.child1());
- NodeIndex child2 = canonicalize(node.child2());
- NodeIndex child3 = canonicalize(node.child3());
-
for (unsigned i = m_indexInBlock; i--;) {
NodeIndex index = m_currentBlock->at(i);
- if (index == child1 || index == child2 || index == child3)
- break;
-
- Node& otherNode = m_graph[index];
- if (node.op() == otherNode.op()
- && node.arithNodeFlags() == otherNode.arithNodeFlags()) {
- NodeIndex otherChild = canonicalize(otherNode.child1());
- if (otherChild == NoNode)
+ Node& node = m_graph[index];
+ if (!node.shouldGenerate())
+ continue;
+ switch (node.op()) {
+ case GetArrayLength:
+ if (node.child1() == array)
return index;
- if (otherChild == child1) {
- otherChild = canonicalize(otherNode.child2());
- if (otherChild == NoNode)
- return index;
- if (otherChild == child2) {
- otherChild = canonicalize(otherNode.child3());
- if (otherChild == NoNode)
- return index;
- if (otherChild == child3)
- return index;
- }
+ break;
+
+ case PutByVal:
+ if (!m_graph.byValIsPure(node))
+ return NoNode;
+ switch (node.arrayMode()) {
+ case ARRAY_STORAGE_TO_HOLE_MODES:
+ return NoNode;
+ default:
+ break;
}
- }
- if (m_graph.clobbersWorld(index))
break;
+
+ default:
+ if (m_graph.clobbersWorld(index))
+ return NoNode;
+ }
}
return NoNode;
}
@@ -216,6 +215,34 @@ private:
return NoNode;
}
+ NodeIndex scopedVarLoadElimination(unsigned scopeChainDepth, unsigned varNumber)
+ {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ Node& node = m_graph[index];
+ switch (node.op()) {
+ case GetScopedVar: {
+ Node& getScopeRegisters = m_graph[node.child1()];
+ Node& getScope = m_graph[getScopeRegisters.child1()];
+ if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
+ return index;
+ break;
+ }
+ case PutScopedVar: {
+ Node& getScope = m_graph[node.child1()];
+ if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
+ return node.child3().index();
+ break;
+ }
+ default:
+ break;
+ }
+ if (m_graph.clobbersWorld(index))
+ break;
+ }
+ return NoNode;
+ }
+
bool globalVarWatchpointElimination(WriteBarrier<Unknown>* registerPointer)
{
for (unsigned i = m_indexInBlock; i--;) {
@@ -267,6 +294,38 @@ private:
return NoNode;
}
+ NodeIndex scopedVarStoreElimination(unsigned scopeChainDepth, unsigned varNumber)
+ {
+ for (unsigned i = m_indexInBlock; i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ Node& node = m_graph[index];
+ if (!node.shouldGenerate())
+ continue;
+ switch (node.op()) {
+ case PutScopedVar: {
+ Node& getScope = m_graph[node.child1()];
+ if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
+ return index;
+ break;
+ }
+
+ case GetScopedVar: {
+ Node& getScopeRegisters = m_graph[node.child1()];
+ Node& getScope = m_graph[getScopeRegisters.child1()];
+ if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
+ return NoNode;
+ break;
+ }
+
+ default:
+ break;
+ }
+ if (m_graph.clobbersWorld(index) || node.canExit())
+ return NoNode;
+ }
+ return NoNode;
+ }
+
NodeIndex getByValLoadElimination(NodeIndex child1, NodeIndex child2)
{
for (unsigned i = m_indexInBlock; i--;) {
@@ -437,7 +496,7 @@ private:
break;
Node& node = m_graph[index];
if (!node.shouldGenerate())
- break;
+ continue;
switch (node.op()) {
case CheckStructure:
case ForwardCheckStructure:
@@ -690,19 +749,35 @@ private:
return NoNode;
}
- NodeIndex getScopeChainLoadElimination(unsigned depth)
+ NodeIndex getScopeLoadElimination(unsigned depth)
{
for (unsigned i = endIndexForPureCSE(); i--;) {
NodeIndex index = m_currentBlock->at(i);
Node& node = m_graph[index];
if (!node.shouldGenerate())
continue;
- if (node.op() == GetScopeChain
+ if (node.op() == GetScope
&& node.scopeChainDepth() == depth)
return index;
}
return NoNode;
}
+
+ NodeIndex getScopeRegistersLoadElimination(unsigned depth)
+ {
+ for (unsigned i = endIndexForPureCSE(); i--;) {
+ NodeIndex index = m_currentBlock->at(i);
+ Node& node = m_graph[index];
+ if (!node.shouldGenerate())
+ continue;
+ if (node.op() == GetScopeRegisters
+ && m_graph[node.scope()].scopeChainDepth() == depth)
+ return index;
+ }
+ return NoNode;
+ }
+
+
NodeIndex getLocalLoadElimination(VirtualRegister local, NodeIndex& relevantLocalOp, bool careAboutClobbering)
{
@@ -787,7 +862,8 @@ private:
return result;
}
- case GetScopeChain:
+ case GetScope:
+ case GetScopeRegisters:
if (m_graph.uncheckedActivationRegisterFor(node.codeOrigin) == local)
result.mayBeAccessed = true;
break;
@@ -1078,11 +1154,15 @@ private:
break;
case GetArrayLength:
- setReplacement(impureCSE(node));
+ setReplacement(getArrayLengthElimination(node.child1().index()));
break;
-
- case GetScopeChain:
- setReplacement(getScopeChainLoadElimination(node.scopeChainDepth()));
+
+ case GetScope:
+ setReplacement(getScopeLoadElimination(node.scopeChainDepth()));
+ break;
+
+ case GetScopeRegisters:
+ setReplacement(getScopeRegistersLoadElimination(m_graph[node.scope()].scopeChainDepth()));
break;
// Handle nodes that are conditionally pure: these are pure, and can
@@ -1106,7 +1186,14 @@ private:
case GetGlobalVar:
setReplacement(globalVarLoadElimination(node.registerPointer()));
break;
-
+
+ case GetScopedVar: {
+ Node& getScopeRegisters = m_graph[node.child1()];
+ Node& getScope = m_graph[getScopeRegisters.child1()];
+ setReplacement(scopedVarLoadElimination(getScope.scopeChainDepth(), node.varNumber()));
+ break;
+ }
+
case GlobalVarWatchpoint:
if (globalVarWatchpointElimination(node.registerPointer()))
eliminate();
@@ -1119,6 +1206,14 @@ private:
eliminate(globalVarStoreElimination(node.registerPointer()));
break;
+ case PutScopedVar: {
+ if (m_graph.m_fixpointState == FixpointNotConverged)
+ break;
+ Node& getScope = m_graph[node.child1()];
+ eliminate(scopedVarStoreElimination(getScope.scopeChainDepth(), node.varNumber()));
+ break;
+ }
+
case GetByVal:
if (m_graph.byValIsPure(node))
setReplacement(getByValLoadElimination(node.child1().index(), node.child2().index()));
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 64d81f526..b02c9991c 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -469,6 +469,12 @@ public:
return isNumberSpeculation(left) && isNumberSpeculation(right);
}
+ // Note that a 'true' return does not actually mean that the ByVal access clobbers nothing.
+ // It really means that it will not clobber the entire world. It's still up to you to
+ // carefully consider things like:
+ // - PutByVal definitely changes the array it stores to, and may even change its length.
+ // - PutByOffset definitely changes the object it stores to.
+ // - and so on.
bool byValIsPure(Node& node)
{
switch (node.arrayMode()) {
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 195135c7b..df6191eab 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -466,7 +466,7 @@ struct Node {
bool hasScopeChainDepth()
{
- return op() == GetScopeChain;
+ return op() == GetScope;
}
unsigned scopeChainDepth()
@@ -475,6 +475,12 @@ struct Node {
return m_opInfo;
}
+ Edge scope()
+ {
+ ASSERT(op() == GetScopeRegisters);
+ return child1();
+ }
+
bool hasResult()
{
return m_flags & NodeResultMask;
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 584e28cca..9c93a8ba3 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -144,10 +144,11 @@ namespace JSC { namespace DFG {
macro(GetByOffset, NodeResultJS) \
macro(PutByOffset, NodeMustGenerate) \
macro(GetArrayLength, NodeResultInt32) \
- macro(GetScopeChain, NodeResultJS) \
- macro(GetScopedVar, NodeResultJS | NodeMustGenerate) \
- macro(PutScopedVar, NodeMustGenerate | NodeClobbersWorld) \
- macro(GetGlobalVar, NodeResultJS | NodeMustGenerate) \
+ macro(GetScope, NodeResultJS) \
+ macro(GetScopeRegisters, NodeResultStorage) \
+ macro(GetScopedVar, NodeResultJS) \
+ macro(PutScopedVar, NodeMustGenerate) \
+ macro(GetGlobalVar, NodeResultJS) \
macro(PutGlobalVar, NodeMustGenerate) \
macro(GlobalVarWatchpoint, NodeMustGenerate) \
macro(PutGlobalVarCheck, NodeMustGenerate) \
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index a918bbbe5..d76fd8018 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -447,7 +447,8 @@ private:
changed |= setPrediction(SpecInt32);
break;
}
-
+
+ case GetScopeRegisters:
case GetButterfly:
case GetIndexedPropertyStorage:
case AllocatePropertyStorage:
@@ -509,7 +510,7 @@ private:
break;
}
- case GetScopeChain: {
+ case GetScope: {
changed |= setPrediction(SpecCellOther);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 690f0dd3e..b05537fdf 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -216,7 +216,7 @@ static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stu
linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
- stubRoutine = FINALIZE_CODE_FOR_STUB(
+ stubRoutine = FINALIZE_CODE_FOR_DFG_STUB(
patchBuffer,
("DFG prototype chain access stub for CodeBlock %p, return point %p",
exec->codeBlock(), successLabel.executableAddress()));
@@ -277,7 +277,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
- stubInfo.stubRoutine = FINALIZE_CODE_FOR_STUB(
+ stubInfo.stubRoutine = FINALIZE_CODE_FOR_DFG_STUB(
patchBuffer,
("DFG GetById array length stub for CodeBlock %p, return point %p",
exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
@@ -506,7 +506,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
RefPtr<JITStubRoutine> stubRoutine =
createJITStubRoutine(
- FINALIZE_CODE(
+ FINALIZE_DFG_CODE(
patchBuffer,
("DFG GetById polymorphic list access for CodeBlock %p, return point %p",
exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
@@ -717,7 +717,7 @@ static void emitPutReplaceStub(
patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone));
patchBuffer.link(failure, failureLabel);
- stubRoutine = FINALIZE_CODE_FOR_STUB(
+ stubRoutine = FINALIZE_CODE_FOR_DFG_STUB(
patchBuffer,
("DFG PutById replace stub for CodeBlock %p, return point %p",
exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
@@ -917,9 +917,11 @@ static void emitPutTransitionStub(
stubRoutine =
createJITStubRoutine(
- FINALIZE_CODE(
+ FINALIZE_DFG_CODE(
patchBuffer,
- ("DFG PutById transition stub for CodeBlock %p, return point %p",
+ ("DFG PutById %stransition stub (%p -> %p) for CodeBlock %p, return point %p",
+ structure->outOfLineCapacity() != oldStructure->outOfLineCapacity() ? "reallocating " : "",
+ oldStructure, structure,
exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
stubInfo.patch.dfg.deltaCallToDone).executableAddress())),
*globalData,
@@ -957,6 +959,11 @@ static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier
&& oldStructure->outOfLineCapacity())
return false;
+ // Skip optimizing the case where we need realloc, and the structure has
+ // indexing storage.
+ if (hasIndexingHeader(oldStructure->indexingType()))
+ return false;
+
normalizePrototypeChain(exec, baseCell);
StructureChain* prototypeChain = structure->prototypeChain(exec);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 0228f846a..e42752d8a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -2382,7 +2382,7 @@ void SpeculativeJIT::compileInstanceOf(Node& node)
// from speculating any more aggressively than we absolutely need to.
JSValueOperand value(this, node.child1());
- SpeculateCellOperand prototype(this, node.child3());
+ SpeculateCellOperand prototype(this, node.child2());
GPRTemporary scratch(this);
GPRReg prototypeReg = prototype.gpr();
@@ -2416,8 +2416,7 @@ void SpeculativeJIT::compileInstanceOf(Node& node)
}
SpeculateCellOperand value(this, node.child1());
- // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
- SpeculateCellOperand prototype(this, node.child3());
+ SpeculateCellOperand prototype(this, node.child2());
GPRTemporary scratch(this);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 22941358a..8039ad2ab 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -3371,7 +3371,7 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case GetScopeChain: {
+ case GetScope: {
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
@@ -3392,27 +3392,42 @@ void SpeculativeJIT::compile(Node& node)
cellResult(resultGPR, m_compileIndex);
break;
}
- case GetScopedVar: {
+ case GetScopeRegisters: {
SpeculateCellOperand scope(this, node.child1());
+ GPRTemporary result(this);
+ GPRReg scopeGPR = scope.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
+ storageResult(resultGPR, m_compileIndex);
+ break;
+ }
+ case GetScopedVar: {
+ StorageOperand registers(this, node.child1());
GPRTemporary resultTag(this);
GPRTemporary resultPayload(this);
+ GPRReg registersGPR = registers.gpr();
GPRReg resultTagGPR = resultTag.gpr();
GPRReg resultPayloadGPR = resultPayload.gpr();
- m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSVariableObject::offsetOfRegisters()), resultPayloadGPR);
- m_jit.load32(JITCompiler::Address(resultPayloadGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
- m_jit.load32(JITCompiler::Address(resultPayloadGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
+ m_jit.load32(JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+ m_jit.load32(JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
break;
}
case PutScopedVar: {
SpeculateCellOperand scope(this, node.child1());
+ StorageOperand registers(this, node.child2());
+ JSValueOperand value(this, node.child3());
GPRTemporary scratchRegister(this);
+ GPRReg scopeGPR = scope.gpr();
+ GPRReg registersGPR = registers.gpr();
+ GPRReg valueTagGPR = value.tagGPR();
+ GPRReg valuePayloadGPR = value.payloadGPR();
GPRReg scratchGPR = scratchRegister.gpr();
- m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSVariableObject::offsetOfRegisters()), scratchGPR);
- JSValueOperand value(this, node.child2());
- m_jit.store32(value.tagGPR(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
- m_jit.store32(value.payloadGPR(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
- writeBarrier(scope.gpr(), value.tagGPR(), node.child2(), WriteBarrierForVariableAccess, scratchGPR);
+
+ m_jit.store32(valueTagGPR, JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+ m_jit.store32(valuePayloadGPR, JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+ writeBarrier(scopeGPR, valueTagGPR, node.child2(), WriteBarrierForVariableAccess, scratchGPR);
noResult(m_compileIndex);
break;
}
@@ -4202,23 +4217,50 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultPayloadGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, index)),
+ resultPayloadGPR);
+
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ resultTagGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ resultPayloadGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultPayloadGPR);
- size_t baseOffset =
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
+ slowArgument.link(&m_jit);
jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
break;
}
@@ -4252,21 +4294,46 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultPayloadGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, index)),
+ resultPayloadGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ resultTagGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
+ m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ resultPayloadGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultPayloadGPR);
- size_t baseOffset =
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- baseOffset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
if (node.codeOrigin.inlineCallFrame) {
@@ -4284,6 +4351,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.argumentsRegisterFor(node.codeOrigin), indexGPR));
}
+ slowArgument.link(&m_jit);
jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 87be658ad..8488d261d 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -3380,7 +3380,7 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case GetScopeChain: {
+ case GetScope: {
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
@@ -3401,23 +3401,39 @@ void SpeculativeJIT::compile(Node& node)
cellResult(resultGPR, m_compileIndex);
break;
}
- case GetScopedVar: {
+ case GetScopeRegisters: {
SpeculateCellOperand scope(this, node.child1());
GPRTemporary result(this);
+ GPRReg scopeGPR = scope.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
+ storageResult(resultGPR, m_compileIndex);
+ break;
+ }
+ case GetScopedVar: {
+ StorageOperand registers(this, node.child1());
+ GPRTemporary result(this);
+ GPRReg registersGPR = registers.gpr();
GPRReg resultGPR = result.gpr();
- m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSVariableObject::offsetOfRegisters()), resultGPR);
- m_jit.loadPtr(JITCompiler::Address(resultGPR, node.varNumber() * sizeof(Register)), resultGPR);
+
+ m_jit.loadPtr(JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register)), resultGPR);
jsValueResult(resultGPR, m_compileIndex);
break;
}
case PutScopedVar: {
SpeculateCellOperand scope(this, node.child1());
+ StorageOperand registers(this, node.child2());
+ JSValueOperand value(this, node.child3());
GPRTemporary scratchRegister(this);
+
+ GPRReg scopeGPR = scope.gpr();
+ GPRReg registersGPR = registers.gpr();
+ GPRReg valueGPR = value.gpr();
GPRReg scratchGPR = scratchRegister.gpr();
- m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSVariableObject::offsetOfRegisters()), scratchGPR);
- JSValueOperand value(this, node.child2());
- m_jit.storePtr(value.gpr(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register)));
- writeBarrier(scope.gpr(), value.gpr(), node.child2(), WriteBarrierForVariableAccess, scratchGPR);
+
+ m_jit.storePtr(valueGPR, JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register)));
+ writeBarrier(scopeGPR, valueGPR, node.child3(), WriteBarrierForVariableAccess, scratchGPR);
noResult(m_compileIndex);
break;
}
@@ -4122,7 +4138,7 @@ void SpeculativeJIT::compile(Node& node)
GPRTemporary result(this);
GPRReg indexGPR = index.gpr();
GPRReg resultGPR = result.gpr();
-
+
if (!isEmptySpeculation(
m_state.variables().operand(
m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type)) {
@@ -4150,18 +4166,40 @@ void SpeculativeJIT::compile(Node& node)
resultGPR,
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
-
+
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, index)),
+ resultGPR);
+ m_jit.signExtend32ToPtr(resultGPR, resultGPR);
+ m_jit.loadPtr(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node.codeOrigin)),
+ resultGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultGPR);
m_jit.signExtend32ToPtr(resultGPR, resultGPR);
m_jit.loadPtr(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight,
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin)),
resultGPR);
+ slowArgument.link(&m_jit);
jsValueResult(resultGPR, m_compileIndex);
break;
}
@@ -4194,15 +4232,36 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::payloadFor(RegisterFile::ArgumentCount)));
}
+ JITCompiler::JumpList slowArgument;
+ JITCompiler::JumpList slowArgumentOutOfBounds;
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ slowArgumentOutOfBounds.append(
+ m_jit.branch32(
+ JITCompiler::AboveOrEqual, indexGPR,
+ Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+
+ COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
+ m_jit.move(ImmPtr(slowArguments), resultGPR);
+ m_jit.load32(
+ JITCompiler::BaseIndex(
+ resultGPR, indexGPR, JITCompiler::TimesEight,
+ OBJECT_OFFSETOF(SlowArgument, index)),
+ resultGPR);
+ m_jit.signExtend32ToPtr(resultGPR, resultGPR);
+ m_jit.loadPtr(
+ JITCompiler::BaseIndex(
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node.codeOrigin)),
+ resultGPR);
+ slowArgument.append(m_jit.jump());
+ }
+ slowArgumentOutOfBounds.link(&m_jit);
+
m_jit.neg32(resultGPR);
m_jit.signExtend32ToPtr(resultGPR, resultGPR);
m_jit.loadPtr(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight,
- ((node.codeOrigin.inlineCallFrame
- ? node.codeOrigin.inlineCallFrame->stackOffset
- : 0) + CallFrame::argumentOffsetIncludingThis(0)) * sizeof(Register)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin)),
resultGPR);
if (node.codeOrigin.inlineCallFrame) {
@@ -4220,6 +4279,7 @@ void SpeculativeJIT::compile(Node& node)
indexGPR));
}
+ slowArgument.link(&m_jit);
jsValueResult(resultGPR, m_compileIndex);
break;
}
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 26453c4f3..613edd08c 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -96,7 +96,7 @@ typedef pthread_t PlatformThread;
static const int SigThreadSuspendResume = SIGUSR2;
#if defined(SA_RESTART)
-static void pthreadSignalHandlerSuspendResume(int signo)
+static void pthreadSignalHandlerSuspendResume(int)
{
sigset_t signalSet;
sigemptyset(&signalSet);
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index ef6cbd5a6..3b3409bd6 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -131,14 +131,6 @@ static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, JSValue value
exceptionData = createInvalidParamError(callFrame, "in" , value);
return true;
}
-
-static NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
-{
- if (value.isObject() && asObject(value)->structure()->typeInfo().implementsHasInstance())
- return false;
- exceptionData = createInvalidParamError(callFrame, "instanceof" , value);
- return true;
-}
#endif
JSValue eval(CallFrame* callFrame)
@@ -202,7 +194,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue
newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
newCallFrame->setThisValue(thisValue);
for (size_t i = 0; i < callFrame->argumentCount(); ++i)
- newCallFrame->setArgument(i, callFrame->argument(i));
+ newCallFrame->setArgument(i, callFrame->argumentAfterCapture(i));
return newCallFrame;
}
@@ -2401,14 +2393,32 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSC API*). Raises an exception if register constructor is not
an valid parameter for instanceof.
*/
- int base = vPC[1].u.operand;
+ int dst = vPC[1].u.operand;
+ int value = vPC[2].u.operand;
+ int base = vPC[3].u.operand;
+ int target = vPC[4].u.operand;
+
JSValue baseVal = callFrame->r(base).jsValue();
- if (isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue))
- goto vm_throw;
+ if (baseVal.isObject()) {
+ TypeInfo info = asObject(baseVal)->structure()->typeInfo();
+ if (info.implementsDefaultHasInstance()) {
+ vPC += OPCODE_LENGTH(op_check_has_instance);
+ NEXT_INSTRUCTION();
+ }
+ if (info.implementsHasInstance()) {
+ JSValue baseVal = callFrame->r(base).jsValue();
+ bool result = asObject(baseVal)->methodTable()->customHasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue());
+ CHECK_FOR_EXCEPTION();
+ callFrame->uncheckedR(dst) = jsBoolean(result);
- vPC += OPCODE_LENGTH(op_check_has_instance);
- NEXT_INSTRUCTION();
+ vPC += target;
+ NEXT_INSTRUCTION();
+ }
+ }
+
+ exceptionValue = createInvalidParamError(callFrame, "instanceof" , baseVal);
+ goto vm_throw;
}
DEFINE_OPCODE(op_instanceof) {
/* instanceof dst(r) value(r) constructor(r) constructorProto(r)
@@ -2425,14 +2435,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int dst = vPC[1].u.operand;
int value = vPC[2].u.operand;
- int base = vPC[3].u.operand;
- int baseProto = vPC[4].u.operand;
-
- JSValue baseVal = callFrame->r(base).jsValue();
-
- ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue));
+ int baseProto = vPC[3].u.operand;
- bool result = asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
+ bool result = JSObject::defaultHasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
CHECK_FOR_EXCEPTION();
callFrame->uncheckedR(dst) = jsBoolean(result);
diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp
index f6ea71e17..b5f4f8278 100644
--- a/Source/JavaScriptCore/jit/JITCall.cpp
+++ b/Source/JavaScriptCore/jit/JITCall.cpp
@@ -66,7 +66,11 @@ void JIT::compileLoadVarargs(Instruction* instruction)
JumpList slowCase;
JumpList end;
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) {
+ bool canOptimize = m_codeBlock->usesArguments()
+ && arguments == m_codeBlock->argumentsRegister()
+ && !m_codeBlock->symbolTable()->slowArguments();
+
+ if (canOptimize) {
emitGetVirtualRegister(arguments, regT0);
slowCase.append(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue()))));
@@ -103,7 +107,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
end.append(jump());
}
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
slowCase.link(this);
JITStubCall stubCall(this, cti_op_load_varargs);
@@ -112,7 +116,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
stubCall.addArgument(Imm32(firstFreeRegister));
stubCall.call(regT1);
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
end.link(this);
}
diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp
index 6195d0bb9..09727d532 100644
--- a/Source/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp
@@ -141,7 +141,11 @@ void JIT::compileLoadVarargs(Instruction* instruction)
JumpList slowCase;
JumpList end;
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) {
+ bool canOptimize = m_codeBlock->usesArguments()
+ && arguments == m_codeBlock->argumentsRegister()
+ && !m_codeBlock->symbolTable()->slowArguments();
+
+ if (canOptimize) {
emitLoadTag(arguments, regT1);
slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
@@ -180,7 +184,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
end.append(jump());
}
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
slowCase.link(this);
JITStubCall stubCall(this, cti_op_load_varargs);
@@ -189,7 +193,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
stubCall.addArgument(Imm32(firstFreeRegister));
stubCall.call(regT3);
- if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister())
+ if (canOptimize)
end.link(this);
}
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index a4f9107df..ed63ad348 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -552,6 +552,7 @@ inline void JIT::emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndI
#if ENABLE(VALUE_PROFILER)
emitArrayProfilingSite(structureAndIndexingType, scratch, m_codeBlock->getOrAddArrayProfile(bytecodeIndex));
#else
+ UNUSED_PARAM(bytecodeIndex);
emitArrayProfilingSite(structureAndIndexingType, scratch, 0);
#endif
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index 642aabb2a..3b7f38dc7 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -407,7 +407,7 @@ void JIT::emitSlow_op_new_object(Instruction* currentInstruction, Vector<SlowCas
void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
{
- unsigned baseVal = currentInstruction[1].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
emitGetVirtualRegister(baseVal, regT0);
@@ -416,20 +416,18 @@ void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
// Check that baseVal 'ImplementsHasInstance'.
loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsHasInstance)));
+ addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));
}
void JIT::emit_op_instanceof(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
unsigned value = currentInstruction[2].u.operand;
- unsigned baseVal = currentInstruction[3].u.operand;
- unsigned proto = currentInstruction[4].u.operand;
+ unsigned proto = currentInstruction[3].u.operand;
// Load the operands (baseVal, proto, and value respectively) into registers.
// We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
emitGetVirtualRegister(value, regT2);
- emitGetVirtualRegister(baseVal, regT0);
emitGetVirtualRegister(proto, regT1);
// Check that proto are cells. baseVal must be a cell - this is checked by op_check_has_instance.
@@ -440,11 +438,6 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
loadPtr(Address(regT1, JSCell::structureOffset()), regT3);
addSlowCase(emitJumpIfNotObject(regT3));
- // Fixme: this check is only needed because the JSC API allows HasInstance to be overridden; we should deprecate this.
- // Check that baseVal 'ImplementsDefaultHasInstance'.
- loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));
-
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
@@ -1452,29 +1445,31 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase
void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- unsigned baseVal = currentInstruction[1].u.operand;
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned value = currentInstruction[2].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_check_has_instance);
+ stubCall.addArgument(value, regT2);
stubCall.addArgument(baseVal, regT2);
- stubCall.call();
+ stubCall.call(dst);
+
+ emitJumpSlowToHot(jump(), currentInstruction[4].u.operand);
}
void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned dst = currentInstruction[1].u.operand;
unsigned value = currentInstruction[2].u.operand;
- unsigned baseVal = currentInstruction[3].u.operand;
- unsigned proto = currentInstruction[4].u.operand;
+ unsigned proto = currentInstruction[3].u.operand;
linkSlowCaseIfNotJSCell(iter, value);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
- linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value, regT2);
- stubCall.addArgument(baseVal, regT2);
stubCall.addArgument(proto, regT2);
stubCall.call(dst);
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index adfb57341..21744fba8 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -543,7 +543,7 @@ void JIT::emitSlow_op_new_object(Instruction* currentInstruction, Vector<SlowCas
void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
{
- unsigned baseVal = currentInstruction[1].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
emitLoadPayload(baseVal, regT0);
@@ -552,20 +552,18 @@ void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
// Check that baseVal 'ImplementsHasInstance'.
loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsHasInstance)));
+ addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));
}
void JIT::emit_op_instanceof(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
unsigned value = currentInstruction[2].u.operand;
- unsigned baseVal = currentInstruction[3].u.operand;
- unsigned proto = currentInstruction[4].u.operand;
+ unsigned proto = currentInstruction[3].u.operand;
// Load the operands into registers.
// We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
emitLoadPayload(value, regT2);
- emitLoadPayload(baseVal, regT0);
emitLoadPayload(proto, regT1);
// Check that proto are cells. baseVal must be a cell - this is checked by op_check_has_instance.
@@ -576,11 +574,6 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
loadPtr(Address(regT1, JSCell::structureOffset()), regT3);
addSlowCase(emitJumpIfNotObject(regT3));
- // Fixme: this check is only needed because the JSC API allows HasInstance to be overridden; we should deprecate this.
- // Check that baseVal 'ImplementsDefaultHasInstance'.
- loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
- addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));
-
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
@@ -604,31 +597,33 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- unsigned baseVal = currentInstruction[1].u.operand;
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned value = currentInstruction[2].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_check_has_instance);
+ stubCall.addArgument(value);
stubCall.addArgument(baseVal);
- stubCall.call();
+ stubCall.call(dst);
+
+ emitJumpSlowToHot(jump(), currentInstruction[4].u.operand);
}
void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned dst = currentInstruction[1].u.operand;
unsigned value = currentInstruction[2].u.operand;
- unsigned baseVal = currentInstruction[3].u.operand;
- unsigned proto = currentInstruction[4].u.operand;
+ unsigned proto = currentInstruction[3].u.operand;
linkSlowCaseIfNotJSCell(iter, value);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
- linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value);
- stubCall.addArgument(baseVal);
stubCall.addArgument(proto);
stubCall.call(dst);
}
diff --git a/Source/JavaScriptCore/jit/JITStubRoutine.h b/Source/JavaScriptCore/jit/JITStubRoutine.h
index 4400589ff..a46fcfd1a 100644
--- a/Source/JavaScriptCore/jit/JITStubRoutine.h
+++ b/Source/JavaScriptCore/jit/JITStubRoutine.h
@@ -153,6 +153,9 @@ protected:
#define FINALIZE_CODE_FOR_STUB(patchBuffer, dataLogArguments) \
(adoptRef(new JITStubRoutine(FINALIZE_CODE((patchBuffer), dataLogArguments))))
+#define FINALIZE_CODE_FOR_DFG_STUB(patchBuffer, dataLogArguments) \
+ (adoptRef(new JITStubRoutine(FINALIZE_DFG_CODE((patchBuffer), dataLogArguments))))
+
} // namespace JSC
#endif // ENABLE(JIT)
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index e63f06cef..da507838a 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -1937,21 +1937,27 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(void, op_check_has_instance)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_check_has_instance)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
- JSValue baseVal = stackFrame.args[0].jsValue();
+ JSValue value = stackFrame.args[0].jsValue();
+ JSValue baseVal = stackFrame.args[1].jsValue();
+
+ if (baseVal.isObject()) {
+ JSObject* baseObject = asObject(baseVal);
+ ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
+ if (baseObject->structure()->typeInfo().implementsHasInstance()) {
+ bool result = baseObject->methodTable()->customHasInstance(baseObject, callFrame, value);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValue::encode(jsBoolean(result));
+ }
+ }
- // ECMA-262 15.3.5.3:
- // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
-#ifndef NDEBUG
- TypeInfo typeInfo(UnspecifiedType);
- ASSERT(!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
-#endif
stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal);
VM_THROW_EXCEPTION_AT_END();
+ return JSValue::encode(JSValue());
}
#if ENABLE(DFG_JIT)
@@ -2082,10 +2088,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
CallFrame* callFrame = stackFrame.callFrame;
JSValue value = stackFrame.args[0].jsValue();
- JSValue baseVal = stackFrame.args[1].jsValue();
- JSValue proto = stackFrame.args[2].jsValue();
+ JSValue proto = stackFrame.args[1].jsValue();
- bool result = CommonSlowPaths::opInstanceOfSlow(callFrame, value, baseVal, proto);
+ ASSERT(!value.isObject() || !proto.isObject());
+
+ bool result = JSObject::defaultHasInstance(callFrame, value, proto);
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(jsBoolean(result));
}
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index e3ef4416e..a4619c816 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -350,6 +350,7 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+ EncodedJSValue JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
@@ -431,7 +432,6 @@ extern "C" {
void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION) WTF_INTERNAL;
int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL;
void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL;
void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION) WTF_INTERNAL;
void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 1ddfca37c..f9833e4ce 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -301,11 +301,13 @@ inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
}
enum EntryKind { Prologue, ArityCheck };
-static SlowPathReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
+static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
{
#if ENABLE(JIT_VERBOSE_OSR)
dataLog("%p: Entered %s with executeCounter = %s\n", codeBlock, name,
codeBlock->llintExecuteCounter().status());
+#else
+ UNUSED_PARAM(name);
#endif
if (!shouldJIT(exec)) {
@@ -718,19 +720,27 @@ LLINT_SLOW_PATH_DECL(slow_path_bitxor)
LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
{
LLINT_BEGIN();
- JSValue baseVal = LLINT_OP_C(1).jsValue();
-#ifndef NDEBUG
- TypeInfo typeInfo(UnspecifiedType);
- ASSERT(!baseVal.isObject()
- || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
-#endif
+
+ JSValue value = LLINT_OP_C(2).jsValue();
+ JSValue baseVal = LLINT_OP_C(3).jsValue();
+ if (baseVal.isObject()) {
+ JSObject* baseObject = asObject(baseVal);
+ ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
+ if (baseObject->structure()->typeInfo().implementsHasInstance()) {
+ pc += pc[4].u.operand;
+ LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
+ }
+ }
LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
}
LLINT_SLOW_PATH_DECL(slow_path_instanceof)
{
LLINT_BEGIN();
- LLINT_RETURN(jsBoolean(CommonSlowPaths::opInstanceOfSlow(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue())));
+ JSValue value = LLINT_OP_C(2).jsValue();
+ JSValue proto = LLINT_OP_C(3).jsValue();
+ ASSERT(!value.isObject() || !proto.isObject());
+ LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
}
LLINT_SLOW_PATH_DECL(slow_path_typeof)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 953bb3a92..53da6424b 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -833,28 +833,21 @@ _llint_op_bitor:
_llint_op_check_has_instance:
traceExecution()
- loadi 4[PC], t1
+ loadi 12[PC], t1
loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
loadp JSCell::m_structure[t0], t0
- btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
- dispatch(2)
+ btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow
+ dispatch(5)
.opCheckHasInstanceSlow:
callSlowPath(_llint_slow_path_check_has_instance)
- dispatch(2)
+ dispatch(0)
_llint_op_instanceof:
traceExecution()
- # Check that baseVal implements the default HasInstance behavior.
- # FIXME: This should be deprecated.
- loadi 12[PC], t1
- loadConstantOrVariablePayloadUnchecked(t1, t0)
- loadp JSCell::m_structure[t0], t0
- btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
-
# Actually do the work.
- loadi 16[PC], t0
+ loadi 12[PC], t0
loadi 4[PC], t3
loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
loadp JSCell::m_structure[t1], t2
@@ -874,11 +867,11 @@ _llint_op_instanceof:
.opInstanceofDone:
storei BooleanTag, TagOffset[cfr, t3, 8]
storei t0, PayloadOffset[cfr, t3, 8]
- dispatch(5)
+ dispatch(4)
.opInstanceofSlow:
callSlowPath(_llint_slow_path_instanceof)
- dispatch(5)
+ dispatch(4)
_llint_op_is_undefined:
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index 812be0ec9..f4ff5c464 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -691,28 +691,21 @@ _llint_op_bitor:
_llint_op_check_has_instance:
traceExecution()
- loadis 8[PB, PC, 8], t1
+ loadis 24[PB, PC, 8], t1
loadConstantOrVariableCell(t1, t0, .opCheckHasInstanceSlow)
loadp JSCell::m_structure[t0], t0
- btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
- dispatch(2)
+ btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow
+ dispatch(5)
.opCheckHasInstanceSlow:
callSlowPath(_llint_slow_path_check_has_instance)
- dispatch(2)
+ dispatch(0)
_llint_op_instanceof:
traceExecution()
- # Check that baseVal implements the default HasInstance behavior.
- # FIXME: This should be deprecated.
- loadis 24[PB, PC, 8], t1
- loadConstantOrVariable(t1, t0)
- loadp JSCell::m_structure[t0], t0
- btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
-
# Actually do the work.
- loadis 32[PB, PC, 8], t0
+ loadis 24[PB, PC, 8], t0
loadis 8[PB, PC, 8], t3
loadConstantOrVariableCell(t0, t1, .opInstanceofSlow)
loadp JSCell::m_structure[t1], t2
@@ -732,11 +725,11 @@ _llint_op_instanceof:
.opInstanceofDone:
orp ValueFalse, t0
storep t0, [cfr, t3, 8]
- dispatch(5)
+ dispatch(4)
.opInstanceofSlow:
callSlowPath(_llint_slow_path_instanceof)
- dispatch(5)
+ dispatch(4)
_llint_op_is_undefined:
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb
index b05f0e57f..d9f9bfa01 100644
--- a/Source/JavaScriptCore/offlineasm/armv7.rb
+++ b/Source/JavaScriptCore/offlineasm/armv7.rb
@@ -353,7 +353,7 @@ def armV7LowerMisplacedImmediates(list)
| node |
if node.is_a? Instruction
case node.opcode
- when "storei", "storep"
+ when "storeb", "storei", "storep"
operands = node.operands
newOperands = []
operands.each {
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index 8469ed441..9975e0767 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -578,7 +578,7 @@ class Instruction
when "loadbs"
$asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int8MemRef};"
when "storeb"
- $asm.putc "#{operands[1].uint8MemRef} = #{operands[0].clValue(:int8)}"
+ $asm.putc "#{operands[1].uint8MemRef} = #{operands[0].clValue(:int8)};"
when "loadh"
$asm.putc "#{operands[1].clValue(:int)} = #{operands[0].uint16MemRef};"
when "loadhs"
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index e5e503ee1..fdf202192 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -343,6 +343,18 @@ void Arguments::tearOff(CallFrame* callFrame)
m_registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[m_numArguments]);
m_registers = m_registerArray.get() + CallFrame::offsetFor(m_numArguments + 1);
+ // If we have a captured argument that logically aliases activation storage,
+ // but we optimize away the activation, the argument needs to tear off into
+ // our storage. The simplest way to do this is to revert it to Normal status.
+ if (m_slowArguments && !m_activation) {
+ for (size_t i = 0; i < m_numArguments; ++i) {
+ if (m_slowArguments[i].status != SlowArgument::Captured)
+ continue;
+ m_slowArguments[i].status = SlowArgument::Normal;
+ m_slowArguments[i].index = CallFrame::argumentOffset(i);
+ }
+ }
+
if (!callFrame->isInlineCallFrame()) {
for (size_t i = 0; i < m_numArguments; ++i)
trySetArgument(callFrame->globalData(), i, callFrame->argumentAfterCapture(i));
@@ -362,20 +374,8 @@ void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)
if (!m_numArguments)
return;
- tearOff(exec);
-
- SharedSymbolTable* symbolTable = activation->symbolTable();
- const SlowArgument* slowArguments = symbolTable->slowArguments();
- if (!slowArguments)
- return;
-
- ASSERT(symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings);
m_activation.set(exec->globalData(), this, activation);
-
- allocateSlowArguments();
- size_t count = min<unsigned>(m_numArguments, symbolTable->parameterCount());
- for (size_t i = 0; i < count; ++i)
- m_slowArguments[i] = slowArguments[i];
+ tearOff(exec);
}
void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index c9d0d503d..40063bead 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -161,6 +161,10 @@ namespace JSC {
if (m_slowArguments)
return;
m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]);
+ for (size_t i = 0; i < m_numArguments; ++i) {
+ ASSERT(m_slowArguments[i].status == SlowArgument::Normal);
+ m_slowArguments[i].index = CallFrame::argumentOffset(i);
+ }
}
inline bool Arguments::tryDeleteArgument(size_t argument)
@@ -210,14 +214,14 @@ namespace JSC {
inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
{
ASSERT(isArgument(argument));
- if (!m_slowArguments || m_slowArguments[argument].status == SlowArgument::Normal)
+ if (!m_slowArguments)
return m_registers[CallFrame::argumentOffset(argument)];
- ASSERT(m_slowArguments[argument].status == SlowArgument::Captured);
- if (!m_activation)
- return m_registers[m_slowArguments[argument].indexIfCaptured];
+ int index = m_slowArguments[argument].index;
+ if (!m_activation || m_slowArguments[argument].status != SlowArgument::Captured)
+ return m_registers[index];
- return m_activation->registerAt(m_slowArguments[argument].indexIfCaptured);
+ return m_activation->registerAt(index);
}
inline void Arguments::finishCreation(CallFrame* callFrame)
@@ -234,6 +238,15 @@ namespace JSC {
m_overrodeCaller = false;
m_isStrictMode = callFrame->codeBlock()->isStrictMode();
+ SharedSymbolTable* symbolTable = callFrame->codeBlock()->symbolTable();
+ const SlowArgument* slowArguments = symbolTable->slowArguments();
+ if (slowArguments) {
+ allocateSlowArguments();
+ size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount());
+ for (size_t i = 0; i < count; ++i)
+ m_slowArguments[i] = slowArguments[i];
+ }
+
// The bytecode generator omits op_tear_off_activation in cases of no
// declared parameters, so we need to tear off immediately.
if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
@@ -254,6 +267,8 @@ namespace JSC {
m_overrodeCaller = false;
m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
+ ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable()->slowArguments());
+
// The bytecode generator omits op_tear_off_activation in cases of no
// declared parameters, so we need to tear off immediately.
if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h
index af98e15fa..3ea6b0471 100644
--- a/Source/JavaScriptCore/runtime/ArrayConventions.h
+++ b/Source/JavaScriptCore/runtime/ArrayConventions.h
@@ -26,8 +26,6 @@
namespace JSC {
-#define CHECK_ARRAY_CONSISTENCY 0
-
// Overview of JSArray
//
// Properties of JSArray objects may be stored in one of three locations:
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index c70e40d77..95cba0936 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -629,6 +629,15 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
return JSValue::encode(result);
}
+inline JSValue getOrHole(JSObject* obj, ExecState* exec, unsigned propertyName)
+{
+ PropertySlot slot(obj);
+ if (obj->getPropertySlot(exec, propertyName, slot))
+ return slot.getValue(exec, propertyName);
+
+ return JSValue();
+}
+
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toObject(exec);
@@ -653,17 +662,21 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
- JSValue iObj = thisObj->get(exec, i);
+ JSValue iObj = getOrHole(thisObj, exec, i);
if (exec->hadException())
return JSValue::encode(jsUndefined());
unsigned themin = i;
JSValue minObj = iObj;
for (unsigned j = i + 1; j < length; ++j) {
- JSValue jObj = thisObj->get(exec, j);
+ JSValue jObj = getOrHole(thisObj, exec, j);
if (exec->hadException())
return JSValue::encode(jsUndefined());
double compareResult;
- if (jObj.isUndefined())
+ if (!jObj)
+ compareResult = 1;
+ else if (!minObj)
+ compareResult = -1;
+ else if (jObj.isUndefined())
compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
else if (minObj.isUndefined())
compareResult = -1;
@@ -682,12 +695,22 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
}
// Swap themin and i
if (themin > i) {
- thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true);
- if (exec->hadException())
+ if (minObj) {
+ thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, i)) {
+ throwTypeError(exec, "Unable to delete property.");
return JSValue::encode(jsUndefined());
- thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true);
- if (exec->hadException())
+ }
+ if (iObj) {
+ thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, themin)) {
+ throwTypeError(exec, "Unable to delete property.");
return JSValue::encode(jsUndefined());
+ }
}
}
return JSValue::encode(thisObj);
@@ -730,7 +753,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
return JSValue::encode(jsUndefined());
resObj->initializeIndex(globalData, k, v);
}
- resObj->completeInitialization(deleteCount);
unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
if (additionalArgs < deleteCount) {
diff --git a/Source/JavaScriptCore/runtime/ArrayStorage.h b/Source/JavaScriptCore/runtime/ArrayStorage.h
index d967d0b5a..1ab936335 100644
--- a/Source/JavaScriptCore/runtime/ArrayStorage.h
+++ b/Source/JavaScriptCore/runtime/ArrayStorage.h
@@ -64,10 +64,6 @@ public:
m_sparseMap.copyFrom(other.m_sparseMap);
m_indexBias = other.m_indexBias;
m_numValuesInVector = other.m_numValuesInVector;
-#if CHECK_ARRAY_CONSISTENCY
- m_initializationIndex = other.m_initializationIndex;
- m_inCompactInitialization = other.m_inCompactInitialization;
-#endif
}
bool inSparseMode()
@@ -78,11 +74,7 @@ public:
WriteBarrier<SparseArrayValueMap> m_sparseMap;
unsigned m_indexBias;
unsigned m_numValuesInVector;
-#if CHECK_ARRAY_CONSISTENCY
- // Needs to be a uintptr_t for alignment purposes.
- uintptr_t m_initializationIndex;
- uintptr_t m_inCompactInitialization;
-#elif USE(JSVALUE32_64)
+#if USE(JSVALUE32_64)
uintptr_t m_padding;
#endif
WriteBarrier<Unknown> m_vector[1];
diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h
index 0e1747b24..e8823d571 100644
--- a/Source/JavaScriptCore/runtime/ClassInfo.h
+++ b/Source/JavaScriptCore/runtime/ClassInfo.h
@@ -81,8 +81,8 @@ namespace JSC {
typedef String (*ClassNameFunctionPtr)(const JSObject*);
ClassNameFunctionPtr className;
- typedef bool (*HasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue, JSValue);
- HasInstanceFunctionPtr hasInstance;
+ typedef bool (*CustomHasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue);
+ CustomHasInstanceFunctionPtr customHasInstance;
typedef void (*PutWithAttributesFunctionPtr)(JSObject*, ExecState*, PropertyName propertyName, JSValue, unsigned attributes);
PutWithAttributesFunctionPtr putDirectVirtual;
@@ -130,7 +130,7 @@ struct MemberCheck##member { \
&ClassName::getOwnNonIndexPropertyNames, \
&ClassName::getPropertyNames, \
&ClassName::className, \
- &ClassName::hasInstance, \
+ &ClassName::customHasInstance, \
&ClassName::putDirectVirtual, \
&ClassName::defineOwnProperty, \
&ClassName::getOwnPropertyDescriptor, \
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
index e4c76ad16..7edd9091c 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
@@ -75,28 +75,6 @@ ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFi
return newExec;
}
-ALWAYS_INLINE bool opInstanceOfSlow(ExecState* exec, JSValue value, JSValue baseVal, JSValue proto)
-{
- ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
- || !value.isObject() || !baseVal.isObject() || !proto.isObject()
- || !asObject(baseVal)->structure()->typeInfo().implementsDefaultHasInstance());
-
-
- // ECMA-262 15.3.5.3:
- // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
- TypeInfo typeInfo(UnspecifiedType);
- if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) {
- exec->globalData().exception = createInvalidParamError(exec, "instanceof", baseVal);
- return false;
- }
- ASSERT(typeInfo.type() != UnspecifiedType);
-
- if (!typeInfo.overridesHasInstance() && !value.isObject())
- return false;
-
- return asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), exec, value, proto);
-}
-
inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
{
if (!baseVal.isObject()) {
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 62211d302..9b2cb164f 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -195,7 +195,7 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil
#elif USE(ICU_UNICODE) && !UCONFIG_NO_FORMATTING
-static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format)
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMilliseconds, LocaleDateTimeFormat format)
{
UDateFormatStyle timeStyle = (format != LocaleDate ? UDAT_LONG : UDAT_NONE);
UDateFormatStyle dateStyle = (format != LocaleTime ? UDAT_LONG : UDAT_NONE);
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 2791c65d4..d7327d564 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -135,7 +135,6 @@ const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExec
FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node)
: ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode())
- , m_numCapturedVariables(0)
, m_forceUsesArguments(node->usesArguments())
, m_parameters(node->parameters())
, m_name(node->ident())
@@ -527,7 +526,6 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* s
m_numParametersForCall = m_codeBlockForCall->numParameters();
ASSERT(m_numParametersForCall);
- m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars;
m_symbolTable.set(exec->globalData(), this, m_codeBlockForCall->symbolTable());
#if ENABLE(JIT)
@@ -570,7 +568,6 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSSco
m_numParametersForConstruct = m_codeBlockForConstruct->numParameters();
ASSERT(m_numParametersForConstruct);
- m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars;
m_symbolTable.set(exec->globalData(), this, m_codeBlockForConstruct->symbolTable());
#if ENABLE(JIT)
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 76ed21d8b..808c78fba 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -692,7 +692,6 @@ namespace JSC {
const Identifier& inferredName() { return m_inferredName; }
JSString* nameValue() const { return m_nameValue.get(); }
size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'!
- unsigned capturedVariableCount() const { return m_numCapturedVariables; }
String paramString() const;
SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
@@ -742,8 +741,7 @@ namespace JSC {
}
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
- unsigned m_numCapturedVariables : 31;
- bool m_forceUsesArguments : 1;
+ bool m_forceUsesArguments;
RefPtr<FunctionParameters> m_parameters;
OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index 455a21877..dd1628b29 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -193,7 +193,6 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
for (size_t i = 0; i < numBoundArgs; ++i)
boundArgs->initializeIndex(exec->globalData(), i, exec->argument(i + 1));
- boundArgs->completeInitialization(numBoundArgs);
// If the [[Class]] internal property of Target is "Function", then ...
// Else set the length own property of F to 0.
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index dc061bc57..c34e10bc8 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -53,7 +53,7 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
if (!thisObject->isTornOff())
return;
- for (size_t i = 0; i < thisObject->storageSize(); ++i)
+ for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i)
visitor.append(&thisObject->storage()[i]);
}
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 8211e7710..442941335 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -41,21 +41,20 @@ namespace JSC {
class JSActivation : public JSVariableObject {
private:
- JSActivation(JSGlobalData& globalData, CallFrame*, SharedSymbolTable*, size_t storageSize);
+ JSActivation(JSGlobalData& globalData, CallFrame*, SharedSymbolTable*);
public:
typedef JSVariableObject Base;
static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* functionExecutable)
{
- size_t storageSize = JSActivation::storageSize(functionExecutable->symbolTable());
JSActivation* activation = new (
NotNull,
allocateCell<JSActivation>(
globalData.heap,
- allocationSize(storageSize)
+ allocationSize(functionExecutable->symbolTable())
)
- ) JSActivation(globalData, callFrame, functionExecutable->symbolTable(), storageSize);
+ ) JSActivation(globalData, callFrame, functionExecutable->symbolTable());
activation->finishCreation(globalData);
return activation;
}
@@ -81,7 +80,9 @@ namespace JSC {
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); }
- bool isValid(const SymbolTableEntry&);
+ WriteBarrierBase<Unknown>& registerAt(int) const;
+ bool isValidIndex(int) const;
+ bool isValid(const SymbolTableEntry&) const;
bool isTornOff();
protected:
@@ -97,19 +98,16 @@ namespace JSC {
static JSValue argumentsGetter(ExecState*, JSValue, PropertyName);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
- static size_t allocationSize(size_t storageSize);
- static size_t storageSize(SharedSymbolTable*);
- static int captureStart(SharedSymbolTable*);
+ static size_t allocationSize(SharedSymbolTable*);
int registerOffset();
- size_t storageSize();
- WriteBarrier<Unknown>* storage(); // storageSize() number of registers.
+ WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
};
extern int activationCount;
extern int allTheThingsCount;
- inline JSActivation::JSActivation(JSGlobalData& globalData, CallFrame* callFrame, SharedSymbolTable* symbolTable, size_t storageSize)
+ inline JSActivation::JSActivation(JSGlobalData& globalData, CallFrame* callFrame, SharedSymbolTable* symbolTable)
: Base(
globalData,
callFrame->lexicalGlobalObject()->activationStructure(),
@@ -119,7 +117,8 @@ namespace JSC {
)
{
WriteBarrier<Unknown>* storage = this->storage();
- for (size_t i = 0; i < storageSize; ++i)
+ size_t captureCount = symbolTable->captureCount();
+ for (size_t i = 0; i < captureCount; ++i)
new(&storage[i]) WriteBarrier<Unknown>;
}
@@ -142,26 +141,9 @@ namespace JSC {
return false;
}
- inline int JSActivation::captureStart(SharedSymbolTable* symbolTable)
- {
- if (symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings)
- return -CallFrame::offsetFor(symbolTable->parameterCountIncludingThis());
- return symbolTable->captureStart();
- }
-
- inline size_t JSActivation::storageSize(SharedSymbolTable* symbolTable)
- {
- return symbolTable->captureEnd() - captureStart(symbolTable);
- }
-
inline int JSActivation::registerOffset()
{
- return -captureStart(symbolTable());
- }
-
- inline size_t JSActivation::storageSize()
- {
- return storageSize(symbolTable());
+ return -symbolTable()->captureStart();
}
inline void JSActivation::tearOff(JSGlobalData& globalData)
@@ -172,23 +154,9 @@ namespace JSC {
WriteBarrierBase<Unknown>* dst = storage() + registerOffset;
WriteBarrierBase<Unknown>* src = m_registers;
- if (symbolTable()->captureMode() == SharedSymbolTable::AllOfTheThings) {
- int from = -registerOffset;
- int to = CallFrame::thisArgumentOffset(); // Skip 'this' because it's not lexically accessible.
- for (int i = from; i < to; ++i)
- dst[i].set(globalData, this, src[i].get());
-
- dst[RegisterFile::ArgumentCount].set(globalData, this, JSValue(
- CallFrame::create(reinterpret_cast<Register*>(src))->argumentCountIncludingThis()));
-
- int captureEnd = symbolTable()->captureEnd();
- for (int i = 0; i < captureEnd; ++i)
- dst[i].set(globalData, this, src[i].get());
- } else {
- int captureEnd = symbolTable()->captureEnd();
- for (int i = symbolTable()->captureStart(); i < captureEnd; ++i)
- dst[i].set(globalData, this, src[i].get());
- }
+ int captureEnd = symbolTable()->captureEnd();
+ for (int i = symbolTable()->captureStart(); i < captureEnd; ++i)
+ dst[i].set(globalData, this, src[i].get());
m_registers = dst;
ASSERT(isTornOff());
@@ -207,22 +175,33 @@ namespace JSC {
);
}
- inline size_t JSActivation::allocationSize(size_t storageSize)
+ inline size_t JSActivation::allocationSize(SharedSymbolTable* symbolTable)
{
size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
- size_t storageSizeInBytes = storageSize * sizeof(WriteBarrier<Unknown>);
+ size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier<Unknown>);
return objectSizeInBytes + storageSizeInBytes;
}
- inline bool JSActivation::isValid(const SymbolTableEntry& entry)
+ inline bool JSActivation::isValidIndex(int index) const
{
- if (entry.getIndex() < captureStart(symbolTable()))
+ if (index < symbolTable()->captureStart())
return false;
- if (entry.getIndex() >= symbolTable()->captureEnd())
+ if (index >= symbolTable()->captureEnd())
return false;
return true;
}
+ inline bool JSActivation::isValid(const SymbolTableEntry& entry) const
+ {
+ return isValidIndex(entry.getIndex());
+ }
+
+ inline WriteBarrierBase<Unknown>& JSActivation::registerAt(int index) const
+ {
+ ASSERT(isValidIndex(index));
+ return Base::registerAt(index);
+ }
+
} // namespace JSC
#endif // JSActivation_h
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index ebbbd41aa..609781c65 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -60,10 +60,6 @@ Butterfly* createArrayButterflyInDictionaryIndexingMode(JSGlobalData& globalData
storage->m_indexBias = 0;
storage->m_sparseMap.clear();
storage->m_numValuesInVector = 0;
-#if CHECK_ARRAY_CONSISTENCY
- storage->m_initializationIndex = 0;
- storage->m_inCompactInitialization = 0;
-#endif
return butterfly;
}
@@ -330,8 +326,6 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count)
bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
{
- checkIndexingConsistency();
-
ArrayStorage* storage = ensureArrayStorage(exec->globalData());
unsigned length = storage->length();
@@ -392,14 +386,11 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
storage->setLength(newLength);
- checkIndexingConsistency();
return true;
}
JSValue JSArray::pop(ExecState* exec)
{
- checkIndexingConsistency();
-
switch (structure()->indexingType()) {
case ArrayClass:
return jsUndefined();
@@ -424,7 +415,6 @@ JSValue JSArray::pop(ExecState* exec)
ASSERT(isLengthWritable());
storage->setLength(index);
- checkIndexingConsistency();
return element;
}
}
@@ -441,7 +431,6 @@ JSValue JSArray::pop(ExecState* exec)
// Call the [[Put]] internal method of O with arguments "length", indx, and true.
setLength(exec, index, true);
// Return element.
- checkIndexingConsistency();
return element;
}
@@ -456,8 +445,6 @@ JSValue JSArray::pop(ExecState* exec)
// - pushing to an array of length 2^32-1 stores the property, but throws a range error.
void JSArray::push(ExecState* exec, JSValue value)
{
- checkIndexingConsistency();
-
switch (structure()->indexingType()) {
case ArrayClass: {
putByIndexBeyondVectorLengthWithArrayStorage(exec, 0, value, true, createInitialArrayStorage(exec->globalData()));
@@ -483,7 +470,6 @@ void JSArray::push(ExecState* exec, JSValue value)
storage->m_vector[length].set(exec->globalData(), this, value);
storage->setLength(length + 1);
++storage->m_numValuesInVector;
- checkIndexingConsistency();
return;
}
@@ -498,7 +484,6 @@ void JSArray::push(ExecState* exec, JSValue value)
// Handled the same as putIndex.
putByIndexBeyondVectorLengthWithArrayStorage(exec, storage->length(), value, true, storage);
- checkIndexingConsistency();
break;
}
@@ -622,7 +607,6 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
// side-effect from swapping the order of equal primitive values.
qsort(storage->m_vector, size, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort);
- checkIndexingConsistency(SortConsistencyCheck);
return;
}
@@ -711,7 +695,6 @@ void JSArray::sort(ExecState* exec)
Heap::heap(this)->popTempSortVector(&values);
- checkIndexingConsistency(SortConsistencyCheck);
return;
}
@@ -807,7 +790,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
case ArrayWithArrayStorage: {
ArrayStorage* storage = m_butterfly->arrayStorage();
- checkIndexingConsistency();
// FIXME: This ignores exceptions raised in the compare function or in toNumber.
@@ -912,7 +894,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
storage->m_numValuesInVector = newUsedVectorLength;
- checkIndexingConsistency(SortConsistencyCheck);
return;
}
@@ -983,8 +964,6 @@ unsigned JSArray::compactForSorting(JSGlobalData& globalData)
{
ASSERT(!inSparseIndexingMode());
- checkIndexingConsistency();
-
switch (structure()->indexingType()) {
case ArrayClass:
return 0;
@@ -1040,8 +1019,6 @@ unsigned JSArray::compactForSorting(JSGlobalData& globalData)
storage->m_numValuesInVector = newUsedVectorLength;
- checkIndexingConsistency(SortConsistencyCheck);
-
return numDefined;
}
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index c46e67863..6e539c9db 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -51,7 +51,6 @@ namespace JSC {
// contents are known at time of creation. Clients of this interface must:
// - null-check the result (indicating out of memory, or otherwise unable to allocate vector).
// - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength.
- // - called 'completeInitialization' after all properties have been initialized.
static JSArray* tryCreateUninitialized(JSGlobalData&, Structure*, unsigned initialLength);
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
@@ -115,10 +114,6 @@ namespace JSC {
storage->m_indexBias = 0;
storage->m_sparseMap.clear();
storage->m_numValuesInVector = 0;
-#if CHECK_ARRAY_CONSISTENCY
- storage->m_initializationIndex = 0;
- storage->m_inCompactInitialization = 0;
-#endif
return butterfly;
}
@@ -147,10 +142,6 @@ namespace JSC {
storage->m_indexBias = 0;
storage->m_sparseMap.clear();
storage->m_numValuesInVector = initialLength;
-#if CHECK_ARRAY_CONSISTENCY
- storage->m_initializationIndex = 0;
- storage->m_inCompactInitialization = true;
-#endif
JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
array->finishCreation(globalData);
@@ -187,7 +178,6 @@ namespace JSC {
for (unsigned i = 0; i < length; ++i)
array->initializeIndex(globalData, i, values.at(i));
- array->completeInitialization(length);
return array;
}
@@ -204,7 +194,6 @@ namespace JSC {
for (unsigned i = 0; i < length; ++i)
array->initializeIndex(globalData, i, values[i]);
- array->completeInitialization(length);
return array;
}
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
index 08d6831c0..3815c144e 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
@@ -89,14 +89,9 @@ JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* global
return function;
}
-bool JSBoundFunction::hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)
+bool JSBoundFunction::customHasInstance(JSObject* object, ExecState* exec, JSValue value)
{
- JSBoundFunction* thisObject = jsCast<JSBoundFunction*>(object);
- // FIXME: our instanceof implementation will have already (incorrectly) performed
- // a [[Get]] of .prototype from the bound function object, which is incorrect!
- // https://bugs.webkit.org/show_bug.cgi?id=68656
- JSValue proto = thisObject->m_targetFunction->get(exec, exec->propertyNames().prototype);
- return thisObject->m_targetFunction->methodTable()->hasInstance(thisObject->m_targetFunction.get(), exec, value, proto);
+ return jsCast<JSBoundFunction*>(object)->m_targetFunction->hasInstance(exec, value);
}
JSBoundFunction::JSBoundFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs)
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.h b/Source/JavaScriptCore/runtime/JSBoundFunction.h
index 5067d194c..05a6ad8e1 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.h
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.h
@@ -39,7 +39,7 @@ public:
static JSBoundFunction* create(ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&);
- static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);
+ static bool customHasInstance(JSObject*, ExecState*, JSValue);
JSObject* targetFunction() { return m_targetFunction.get(); }
JSValue boundThis() { return m_boundThis.get(); }
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index e050a53ef..739247fb2 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -199,7 +199,7 @@ void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, Enumera
ASSERT_NOT_REACHED();
}
-bool JSCell::hasInstance(JSObject*, ExecState*, JSValue, JSValue)
+bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue)
{
ASSERT_NOT_REACHED();
return false;
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index d6abcba99..cf6f4ec45 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -160,7 +160,7 @@ namespace JSC {
static NO_RETURN_DUE_TO_ASSERT void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static NO_RETURN_DUE_TO_ASSERT void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static String className(const JSObject*);
- static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
+ JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue);
static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 27f68e55b..3d643a266 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -310,9 +310,9 @@ void JSGlobalObject::reset(JSValue prototype)
putDirectWithoutTransition(exec->globalData(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum);
putDirectWithoutTransition(exec->globalData(), Identifier(exec, "JSON"), JSONObject::create(exec, this, JSONObject::createStructure(exec->globalData(), this, m_objectPrototype.get())), DontEnum);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Math"), MathObject::create(exec, this, MathObject::createStructure(exec->globalData(), this, m_objectPrototype.get())), DontEnum);
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "Math"), MathObject::create(exec, this, MathObject::createStructure(exec->globalData(), this, m_objectPrototype.get())), DontEnum | DontDelete),
GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly)
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 229d1aea6..acff8a6ae 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -341,7 +341,6 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
JSObject* thisObject = jsCast<JSObject*>(cell);
- thisObject->checkIndexingConsistency();
if (propertyName > MAX_ARRAY_INDEX) {
PutPropertySlot slot(shouldThrow);
@@ -372,7 +371,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
++storage->m_numValuesInVector;
valueSlot.set(exec->globalData(), thisObject, value);
- thisObject->checkIndexingConsistency();
return;
}
@@ -400,7 +398,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
}
valueSlot.set(exec->globalData(), thisObject, value);
- thisObject->checkIndexingConsistency();
return;
}
@@ -409,7 +406,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
}
thisObject->putByIndexBeyondVectorLength(exec, propertyName, value, shouldThrow);
- thisObject->checkIndexingConsistency();
}
ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(JSGlobalData& globalData, ArrayStorage* storage)
@@ -485,10 +481,6 @@ ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned le
result->m_sparseMap.clear();
result->m_numValuesInVector = 0;
result->m_indexBias = 0;
-#if CHECK_ARRAY_CONSISTENCY
- result->m_initializationIndex = 0;
- result->m_inCompactInitialization = 0;
-#endif
Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedIndexingTransition());
setButterfly(globalData, newButterfly, newStructure);
return result;
@@ -717,7 +709,6 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
}
}
- thisObject->checkIndexingConsistency();
return true;
}
@@ -792,7 +783,18 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, PropertyName p
return 0;
}
-bool JSObject::hasInstance(JSObject*, ExecState* exec, JSValue value, JSValue proto)
+bool JSObject::hasInstance(ExecState* exec, JSValue value)
+{
+ TypeInfo info = structure()->typeInfo();
+ if (info.implementsDefaultHasInstance())
+ return defaultHasInstance(exec, value, get(exec, exec->propertyNames().prototype));
+ if (info.implementsHasInstance())
+ return methodTable()->customHasInstance(this, exec, value);
+ throwError(exec, createInvalidParamError(exec, "instanceof" , this));
+ return false;
+}
+
+bool JSObject::defaultHasInstance(ExecState* exec, JSValue value, JSValue proto)
{
if (!value.isObject())
return false;
@@ -1570,49 +1572,6 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
return true;
}
-#if CHECK_ARRAY_CONSISTENCY
-void JSObject::checkIndexingConsistency(ConsistencyCheckType type)
-{
- ArrayStorage* storage = arrayStorageOrNull();
- if (!storage)
- return;
-
- ASSERT(!storage->m_inCompactInitialization);
-
- ASSERT(storage);
- if (type == SortConsistencyCheck)
- ASSERT(!storage->m_sparseMap);
-
- unsigned numValuesInVector = 0;
- for (unsigned i = 0; i < storage->vectorLength(); ++i) {
- if (JSValue value = storage->m_vector[i].get()) {
- ASSERT(i < storage->length());
- if (type != DestructorConsistencyCheck)
- value.isUndefined(); // Likely to crash if the object was deallocated.
- ++numValuesInVector;
- } else {
- if (type == SortConsistencyCheck)
- ASSERT(i >= storage->m_numValuesInVector);
- }
- }
- ASSERT(numValuesInVector == storage->m_numValuesInVector);
- ASSERT(numValuesInVector <= storage->length());
-
- if (m_sparseValueMap) {
- SparseArrayValueMap::const_iterator end = m_sparseValueMap->end();
- for (SparseArrayValueMap::const_iterator it = m_sparseValueMap->begin(); it != end; ++it) {
- unsigned index = it->first;
- ASSERT(index < storage->length());
- ASSERT(index >= storage->vectorLength());
- ASSERT(index <= MAX_ARRAY_INDEX);
- ASSERT(it->second);
- if (type != DestructorConsistencyCheck)
- it->second.getNonSparseMode().isUndefined(); // Likely to crash if the object was deallocated.
- }
- }
-}
-#endif // CHECK_ARRAY_CONSISTENCY
-
Butterfly* JSObject::growOutOfLineStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
{
ASSERT(newSize > oldSize);
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index bf2dae20d..bb59eb32b 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -259,15 +259,6 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
-#if CHECK_ARRAY_CONSISTENCY
- ASSERT(storage->m_inCompactInitialization);
- // Check that we are initializing the next index in sequence.
- ASSERT(i == storage->m_initializationIndex);
- // tryCreateUninitialized set m_numValuesInVector to the initialLength,
- // check we do not try to initialize more than this number of properties.
- ASSERT(storage->m_initializationIndex < storage->m_numValuesInVector);
- storage->m_initializationIndex++;
-#endif
ASSERT(i < storage->length());
ASSERT(i < storage->m_numValuesInVector);
storage->m_vector[i].set(globalData, this, v);
@@ -278,27 +269,6 @@ namespace JSC {
}
}
- void completeInitialization(unsigned newLength)
- {
- switch (structure()->indexingType()) {
- case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
- ArrayStorage* storage = m_butterfly->arrayStorage();
- // Check that we have initialized as meny properties as we think we have.
- UNUSED_PARAM(storage);
- ASSERT_UNUSED(newLength, newLength == storage->length());
-#if CHECK_ARRAY_CONSISTENCY
- // Check that the number of propreties initialized matches the initialLength.
- ASSERT(storage->m_initializationIndex == m_storage->m_numValuesInVector);
- ASSERT(storage->m_inCompactInitialization);
- storage->m_inCompactInitialization = false;
-#endif
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
bool inSparseIndexingMode()
{
switch (structure()->indexingType()) {
@@ -336,7 +306,8 @@ namespace JSC {
JS_EXPORT_PRIVATE static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
- JS_EXPORT_PRIVATE static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
+ bool hasInstance(ExecState*, JSValue);
+ static bool defaultHasInstance(ExecState*, JSValue, JSValue prototypeProperty);
JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
@@ -591,13 +562,6 @@ namespace JSC {
bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
- enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck };
-#if !CHECK_ARRAY_CONSISTENCY
- void checkIndexingConsistency(ConsistencyCheckType = NormalConsistencyCheck) { }
-#else
- void checkIndexingConsistency(ConsistencyCheckType = NormalConsistencyCheck);
-#endif
-
void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*);
bool increaseVectorLength(JSGlobalData&, unsigned newLength);
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 16c0b5d43..b164948a5 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -35,6 +35,7 @@
#include <wtf/PageBlock.h>
#include <wtf/StdLibExtras.h>
#include <wtf/StringExtras.h>
+#include <wtf/UnusedParam.h>
#if OS(DARWIN) && ENABLE(PARALLEL_GC)
#include <sys/sysctl.h>
@@ -101,6 +102,8 @@ static unsigned computeNumberOfGCMarkers(int maxNumberOfGCMarkers)
ASSERT(cpusToUse >= 1);
if (cpusToUse < 1)
cpusToUse = 1;
+#else
+ UNUSED_PARAM(maxNumberOfGCMarkers);
#endif
return cpusToUse;
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h
index 5427a009b..6063dbab4 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.h
+++ b/Source/JavaScriptCore/runtime/SymbolTable.h
@@ -49,12 +49,12 @@ namespace JSC {
SlowArgument()
: status(Normal)
- , indexIfCaptured(0)
+ , index(0)
{
}
Status status;
- int indexIfCaptured; // If status is 'Captured', indexIfCaptured is our index in the CallFrame.
+ int index; // If status is 'Deleted', index is bogus.
};
static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
@@ -360,20 +360,14 @@ namespace JSC {
bool usesNonStrictEval() { return m_usesNonStrictEval; }
void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
- enum CaptureMode {
- SomeOfTheThings,
- AllOfTheThings
- };
-
- CaptureMode captureMode() { return m_captureMode; }
- void setCaptureMode(CaptureMode captureMode) { m_captureMode = captureMode; }
-
int captureStart() { return m_captureStart; }
void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
int captureEnd() { return m_captureEnd; }
void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
+ int captureCount() { return m_captureEnd - m_captureStart; }
+
int parameterCount() { return m_parameterCountIncludingThis - 1; }
int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
@@ -389,7 +383,6 @@ namespace JSC {
: JSCell(globalData, globalData.sharedSymbolTableStructure.get())
, m_parameterCountIncludingThis(0)
, m_usesNonStrictEval(false)
- , m_captureMode(SomeOfTheThings)
, m_captureStart(0)
, m_captureEnd(0)
{
@@ -398,7 +391,6 @@ namespace JSC {
int m_parameterCountIncludingThis;
bool m_usesNonStrictEval;
- CaptureMode m_captureMode;
int m_captureStart;
int m_captureEnd;
diff --git a/Source/JavaScriptCore/tests/mozilla/expected.html b/Source/JavaScriptCore/tests/mozilla/expected.html
index 06136de27..13c0139f5 100644
--- a/Source/JavaScriptCore/tests/mozilla/expected.html
+++ b/Source/JavaScriptCore/tests/mozilla/expected.html
@@ -9,9 +9,9 @@ Test List: All tests<br>
Skip List: ecma/Date/15.9.2.1.js, ecma/Date/15.9.2.2-1.js, ecma/Date/15.9.2.2-2.js, ecma/Date/15.9.2.2-3.js, ecma/Date/15.9.2.2-4.js, ecma/Date/15.9.2.2-5.js, ecma/Date/15.9.2.2-6.js, ecma_3/Date/15.9.5.7.js, ecma/Date/15.9.5.14.js, ecma/Date/15.9.5.31-1.js, ecma/Date/15.9.5.34-1.js<br>
1124 test(s) selected, 1116 test(s) completed, 44 failures reported (3.94% failed)<br>
Engine command line: "/Volumes/Data/Saxony/OpenSource/WebKitBuild/Debug/jsc" <br>
-OS type: Darwin Bearclaw-Kaliber.local 12.0.0 Darwin Kernel Version 12.0.0: Sun Jun 24 23:00:16 PDT 2012; root:xnu-2050.7.9~1/RELEASE_X86_64 x86_64<br>
-Testcase execution time: 52 seconds.<br>
-Tests completed on Thu Sep 6 15:11:19 2012.<br><br>
+OS type: Darwin Bearclaw-Kaliber.local 12.0.0 Darwin Kernel Version 12.0.0: Fri Jun 22 20:01:10 PDT 2012; root:xnu-2050.7.7~1/RELEASE_X86_64 x86_64<br>
+Testcase execution time: 54 seconds.<br>
+Tests completed on Fri Sep 21 18:29:47 2012.<br><br>
[ <a href='#fail_detail'>Failure Details</a> | <a href='#retest_list'>Retest List</a> | <a href='menu.html'>Test Selection Page</a> ]<br>
<hr>
<a name='fail_detail'></a>
@@ -80,7 +80,7 @@ f.arity = undefined FAILED! expected: 3<br>
Testcase terminated with signal 0<br>
Complete testcase output was:<br>
function-001.js functions not separated by semicolons are errors in version 120 and higher<br>
-eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
+eval("function f(){}function g(){}") = undefined PASSED!<br>
</tt><br>
<a name='failure9'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/regexparg-1.js'>js1_2/function/regexparg-1.js</a> failed</b> <br>
[ <a href='#failure8'>Previous Failure</a> | <a href='#failure10'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
@@ -163,7 +163,7 @@ Testcase terminated with signal 0<br>
Complete testcase output was:<br>
BUGNUMBER: 10278<br>
function-001.js functions not separated by semicolons are errors in version 120 and higher<br>
-eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
+eval("function f(){}function g(){}") = undefined PASSED!<br>
</tt><br>
<a name='failure19'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/script-001.js'>js1_3/Script/script-001.js</a> failed</b> <br>
[ <a href='#failure18'>Previous Failure</a> | <a href='#failure20'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
@@ -181,7 +181,7 @@ Testcase terminated with signal 0<br>
Complete testcase output was:<br>
BUGNUMBER: 10278<br>
function-001.js functions not separated by semicolons are errors in version 120 and higher<br>
-eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
+eval("function f(){}function g(){}") = undefined PASSED!<br>
</tt><br>
<a name='failure21'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-001.js'>js1_5/Exceptions/catchguard-001.js</a> failed</b> <br>
[ <a href='#failure20'>Previous Failure</a> | <a href='#failure22'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
@@ -437,7 +437,7 @@ global code@./js1_6/String/regress-306591.js:48<br>
<pre>
<a name='retest_list'></a>
<h2>Retest List</h2><br>
-# Retest List, squirrelfish, generated Thu Sep 6 15:11:19 2012.
+# Retest List, squirrelfish, generated Fri Sep 21 18:29:47 2012.
# Original test base was: All tests.
# 1116 of 1124 test(s) were completed, 44 failures reported.
ecma_2/Exceptions/function-001.js
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_2/function/function-001-n.js b/Source/JavaScriptCore/tests/mozilla/js1_2/function/function-001-n.js
index 5ae01a956..99e044229 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_2/function/function-001-n.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_2/function/function-001-n.js
@@ -53,7 +53,7 @@
testcases[tc++] = new TestCase(
SECTION,
"eval(\"function f(){}function g(){}\")",
- "error",
+ undefined,
eval("function f(){}function g(){}") );
test();
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_3/Script/function-001-n.js b/Source/JavaScriptCore/tests/mozilla/js1_3/Script/function-001-n.js
index 5b4add048..7d42ce217 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_3/Script/function-001-n.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_3/Script/function-001-n.js
@@ -53,7 +53,7 @@
testcases[tc++] = new TestCase(
SECTION,
"eval(\"function f(){}function g(){}\")",
- "error",
+ undefined,
eval("function f(){}function g(){}") );
test();
diff --git a/Source/JavaScriptCore/tests/mozilla/js1_3/regress/function-001-n.js b/Source/JavaScriptCore/tests/mozilla/js1_3/regress/function-001-n.js
index 5b4add048..7d42ce217 100644
--- a/Source/JavaScriptCore/tests/mozilla/js1_3/regress/function-001-n.js
+++ b/Source/JavaScriptCore/tests/mozilla/js1_3/regress/function-001-n.js
@@ -53,7 +53,7 @@
testcases[tc++] = new TestCase(
SECTION,
"eval(\"function f(){}function g(){}\")",
- "error",
+ undefined,
eval("function f(){}function g(){}") );
test();