RegExpMatchesArray doesn't know how to have a bad time
https://bugs.webkit.org/show_bug.cgi?id=155069
Reviewed by Yusuke Suzuki.
Source/JavaScriptCore:
In trunk if we are having a bad time, the regexp matches array is still allocated with a
non-slow-put indexing shape, which makes it have the wrong behavior on indexed setters on
the prototype chain.
Getting this to work right requires introducing bad time code paths into the regexp matches
array. It also requires something more drastic: making this code not play games with the
global object. The code that creates the matches array needs to have the actual global
object of the regexp native function that it's logically created by.
This is totally different from how we've handled global objects in the past because it means
that the global object is not a constant. Normally we can make it a constant because a
script executable will know its global object. But with native functions, it's the function
instance that knows the global object - not the native executable. When we inline a native
intrinsic, we are guaranteed to know the native executable but we're not guaranteed to know
the functon instance. This means that the global object may be a variable that gets computed
by looking at the instance at run-time. So, the RegExpExec/RegExpTest nodes in DFG IR now
take a global object child. That also meant adding a new node type, GetGlobalObject, which
does the thing to the callee that CallFrame::lexicalGlobalObject() would have done.
Eventually, we'll probably have to make other native intrinsics also use GetGlobalObject. It
turns out that this really isn't so bad because usually it's constant-folded anyway, since
although the intrinsic code supports executable-based inlining (which leaves the callee
instance as an unknown), it happens rarely for intrinsics. So, conveying the global object
via a child isn't any worse than conveying it via meta-data, and it's probably better than
telling the inliner not to do executable-based inlining of native intrinsics. That would
have been a confusing special-case.
This is perf-neutral on my machines but it fixes a bug and it unlocks some interesting
possibilities. For example, RegExpExec can now make a firm promise about the type of array
it's creating.
This also contains some other changes:
- We are now using Structure::addPropertyTransition() in a lot of places even though it was
meant to be an internal method with a quirky contract - for example if only works if you
know that there is not existing transition. This relaxes this constraint.
- Restores the use of "*" for heap references in JSString.h. It's very unusual to have heap
references pointed at with "&", since we don't currently do that anywhere. The fact that
it was using the wrong reference type also meant that the code couldn't elegantly make use
of some our GC pointer helpers like jsCast<>.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::attemptToInlineCall):
(JSC::DFG::ByteCodeParser::handleMinMax):
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileSkipScope):
(JSC::DFG::SpeculativeJIT::compileGetGlobalObject):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileSkipScope):
(JSC::FTL::DFG::LowerDFGToB3::compileGetGlobalObject):
(JSC::FTL::DFG::LowerDFGToB3::compileGetClosureVar):
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpExec):
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpTest):
(JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
* jit/JITOperations.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::haveABadTime):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
* runtime/JSObject.h:
(JSC::JSObject::putDirectInternal):
* runtime/JSString.h:
(JSC::jsString):
(JSC::jsSubstring):
* runtime/RegExpCachedResult.cpp:
(JSC::RegExpCachedResult::lastResult):
* runtime/RegExpMatchesArray.cpp:
(JSC::tryCreateUninitializedRegExpMatchesArray):
(JSC::createRegExpMatchesArray):
(JSC::createStructureImpl):
(JSC::createRegExpMatchesArrayStructure):
(JSC::createRegExpMatchesArraySlowPutStructure):
* runtime/RegExpMatchesArray.h:
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::put):
(JSC::RegExpObject::exec):
(JSC::RegExpObject::match):
* runtime/RegExpObject.h:
(JSC::RegExpObject::getLastIndex):
(JSC::RegExpObject::test):
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncTest):
(JSC::regExpProtoFuncExec):
(JSC::regExpProtoFuncCompile):
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncMatch):
* runtime/Structure.cpp:
(JSC::Structure::suggestedArrayStorageTransition):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::addNewPropertyTransition):
* runtime/Structure.h:
* tests/stress/regexp-matches-array-bad-time.js: Added.
* tests/stress/regexp-matches-array-slow-put.js: Added.
LayoutTests:
* js/regress/regexp-exec-expected.txt: Added.
* js/regress/regexp-exec.html: Added.
* js/regress/script-tests/regexp-exec.js: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@197641 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index 3e72cda..9cfb03f 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -1554,17 +1554,29 @@
}
case RegExpExec:
- if (node->child1().useKind() == RegExpObjectUse
- && node->child2().useKind() == StringUse) {
+ if (node->child2().useKind() == RegExpObjectUse
+ && node->child3().useKind() == StringUse) {
// This doesn't clobber the world since there are no conversions to perform.
} else
clobberWorld(node->origin.semantic, clobberLimit);
- forNode(node).makeHeapTop();
+ if (JSValue globalObjectValue = forNode(node->child1()).m_value) {
+ if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(globalObjectValue)) {
+ if (!globalObject->isHavingABadTime()) {
+ m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
+ Structure* structure = globalObject->regExpMatchesArrayStructure();
+ m_graph.registerStructure(structure);
+ forNode(node).set(m_graph, structure);
+ forNode(node).merge(SpecOther);
+ break;
+ }
+ }
+ }
+ forNode(node).setType(m_graph, SpecOther | SpecArray);
break;
case RegExpTest:
- if (node->child1().useKind() == RegExpObjectUse
- && node->child2().useKind() == StringUse) {
+ if (node->child2().useKind() == RegExpObjectUse
+ && node->child3().useKind() == StringUse) {
// This doesn't clobber the world since there are no conversions to perform.
} else
clobberWorld(node->origin.semantic, clobberLimit);
@@ -1882,6 +1894,33 @@
break;
}
+ case GetGlobalObject: {
+ JSValue child = forNode(node->child1()).value();
+ if (child) {
+ setConstant(node, *m_graph.freeze(JSValue(asObject(child)->globalObject())));
+ break;
+ }
+
+ if (forNode(node->child1()).m_structure.isFinite()) {
+ JSGlobalObject* globalObject = nullptr;
+ bool ok = true;
+ forNode(node->child1()).m_structure.forEach(
+ [&] (Structure* structure) {
+ if (!globalObject)
+ globalObject = structure->globalObject();
+ else if (globalObject != structure->globalObject())
+ ok = false;
+ });
+ if (globalObject && ok) {
+ setConstant(node, *m_graph.freeze(JSValue(globalObject)));
+ break;
+ }
+ }
+
+ forNode(node).setType(m_graph, SpecObjectOther);
+ break;
+ }
+
case GetClosureVar:
if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
setConstant(node, *m_graph.freeze(value));
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 0826a83..6cadf89 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -202,7 +202,7 @@
void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry.
// Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
template<typename ChecksFunctor>
- bool handleIntrinsicCall(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
+ bool handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
template<typename ChecksFunctor>
bool handleIntrinsicGetter(int resultOperand, const GetByIdVariant& intrinsicVariant, Node* thisNode, const ChecksFunctor& insertChecks);
template<typename ChecksFunctor>
@@ -1601,7 +1601,7 @@
Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
if (intrinsic != NoIntrinsic) {
- if (handleIntrinsicCall(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
+ if (handleIntrinsicCall(callTargetNode, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
RELEASE_ASSERT(didInsertChecks);
addToGraph(Phantom, callTargetNode);
emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
@@ -1991,7 +1991,7 @@
}
template<typename ChecksFunctor>
-bool ByteCodeParser::handleIntrinsicCall(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
+bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
{
switch (intrinsic) {
@@ -2172,7 +2172,7 @@
return false;
insertChecks();
- Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
+ Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
set(VirtualRegister(resultOperand), regExpExec);
return true;
@@ -2183,7 +2183,7 @@
return false;
insertChecks();
- Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
+ Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
set(VirtualRegister(resultOperand), regExpExec);
return true;
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index 40cce0f..d0f07d9 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -134,6 +134,7 @@
case ArithLog:
case GetScope:
case SkipScope:
+ case GetGlobalObject:
case StringCharCodeAt:
case CompareStrictEq:
case IsUndefined:
@@ -1078,8 +1079,8 @@
case RegExpExec:
case RegExpTest:
- if (node->child1().useKind() == RegExpObjectUse
- && node->child2().useKind() == StringUse) {
+ if (node->child2().useKind() == RegExpObjectUse
+ && node->child3().useKind() == StringUse) {
read(RegExpState);
write(RegExpState);
return;
diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
index 7004323..49e8e9f 100644
--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
@@ -111,6 +111,7 @@
case CheckArray:
case GetScope:
case SkipScope:
+ case GetGlobalObject:
case GetClosureVar:
case PutClosureVar:
case GetRegExpObjectLastIndex:
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 234045f..e119bcd 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -879,11 +879,13 @@
case RegExpExec:
case RegExpTest: {
- if (node->child1()->shouldSpeculateRegExpObject()) {
- fixEdge<RegExpObjectUse>(node->child1());
+ fixEdge<KnownCellUse>(node->child1());
+
+ if (node->child2()->shouldSpeculateRegExpObject()) {
+ fixEdge<RegExpObjectUse>(node->child2());
- if (node->child2()->shouldSpeculateString())
- fixEdge<StringUse>(node->child2());
+ if (node->child3()->shouldSpeculateString())
+ fixEdge<StringUse>(node->child3());
}
break;
}
@@ -1049,7 +1051,8 @@
case SkipScope:
case GetScope:
case GetGetter:
- case GetSetter: {
+ case GetSetter:
+ case GetGlobalObject: {
fixEdge<KnownCellUse>(node->child1());
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 5200c4d..0131538 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -212,6 +212,7 @@
macro(GetTypedArrayByteOffset, NodeResultInt32) \
macro(GetScope, NodeResultJS) \
macro(SkipScope, NodeResultJS) \
+ macro(GetGlobalObject, NodeResultJS) \
macro(GetClosureVar, NodeResultJS) \
macro(PutClosureVar, NodeMustGenerate) \
macro(GetGlobalVar, NodeResultJS) \
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index d7a22eb..d2c1447 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -619,17 +619,17 @@
return JSValue::encode(array->pop(exec));
}
-EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, RegExpObject* regExpObject, JSString* argument)
+EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
{
- VM& vm = exec->vm();
+ VM& vm = globalObject->vm();
NativeCallFrameTracer tracer(&vm, exec);
- return JSValue::encode(regExpObject->exec(exec, argument));
+ return JSValue::encode(regExpObject->exec(exec, globalObject, argument));
}
-EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
+EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
{
- VM& vm = exec->vm();
+ VM& vm = globalObject->vm();
NativeCallFrameTracer tracer(&vm, exec);
JSValue argument = JSValue::decode(encodedArgument);
@@ -637,12 +637,12 @@
JSString* input = argument.toStringOrNull(exec);
if (!input)
return JSValue::encode(jsUndefined());
- return JSValue::encode(regExpObject->exec(exec, input));
+ return JSValue::encode(regExpObject->exec(exec, globalObject, input));
}
-EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
+EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
{
- VM& vm = exec->vm();
+ VM& vm = globalObject->vm();
NativeCallFrameTracer tracer(&vm, exec);
JSValue base = JSValue::decode(encodedBase);
@@ -654,20 +654,20 @@
JSString* input = argument.toStringOrNull(exec);
if (!input)
return JSValue::encode(jsUndefined());
- return JSValue::encode(asRegExpObject(base)->exec(exec, input));
+ return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
}
-size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, RegExpObject* regExpObject, JSString* input)
+size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
{
- VM& vm = exec->vm();
+ VM& vm = globalObject->vm();
NativeCallFrameTracer tracer(&vm, exec);
- return regExpObject->test(exec, input);
+ return regExpObject->test(exec, globalObject, input);
}
-size_t JIT_OPERATION operationRegExpTest(ExecState* exec, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
+size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
{
- VM& vm = exec->vm();
+ VM& vm = globalObject->vm();
NativeCallFrameTracer tracer(&vm, exec);
JSValue argument = JSValue::decode(encodedArgument);
@@ -675,12 +675,12 @@
JSString* input = argument.toStringOrNull(exec);
if (!input)
return false;
- return regExpObject->test(exec, input);
+ return regExpObject->test(exec, globalObject, input);
}
-size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
+size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
{
- VM& vm = exec->vm();
+ VM& vm = globalObject->vm();
NativeCallFrameTracer tracer(&vm, exec);
JSValue base = JSValue::decode(encodedBase);
@@ -694,7 +694,7 @@
JSString* input = argument.toStringOrNull(exec);
if (!input)
return false;
- return asRegExpObject(base)->test(exec, input);
+ return asRegExpObject(base)->test(exec, globalObject, input);
}
size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index 7247f2b..d3c56df 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -101,13 +101,13 @@
EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState*, double value, JSArray*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState*, JSArray*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, RegExpObject*, JSString*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
// These comparisons return a boolean within a size_t such that the value is zero extended to fill the register.
-size_t JIT_OPERATION operationRegExpTestString(ExecState*, RegExpObject*, JSString*) WTF_INTERNAL;
-size_t JIT_OPERATION operationRegExpTest(ExecState*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
-size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
+size_t JIT_OPERATION operationRegExpTestString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
+size_t JIT_OPERATION operationRegExpTest(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
+size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 666ad62..e492610 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -550,7 +550,8 @@
break;
}
- case SkipScope: {
+ case SkipScope:
+ case GetGlobalObject: {
changed |= setPrediction(SpecObjectOther);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
index b8735bb..a0dc5cb 100644
--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
@@ -207,6 +207,7 @@
case ArrayifyToStructure:
case GetScope:
case SkipScope:
+ case GetGlobalObject:
case GetClosureVar:
case PutClosureVar:
case GetGlobalVar:
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 6c24942..09913ea 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -5342,6 +5342,16 @@
cellResult(result.gpr(), node);
}
+void SpeculativeJIT::compileGetGlobalObject(Node* node)
+{
+ SpeculateCellOperand object(this, node->child1());
+ GPRTemporary result(this);
+ GPRTemporary scratch(this);
+ m_jit.emitLoadStructure(object.gpr(), result.gpr(), scratch.gpr());
+ m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), result.gpr());
+ cellResult(result.gpr(), node);
+}
+
void SpeculativeJIT::compileGetArrayLength(Node* node)
{
switch (node->arrayMode().type()) {
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 59d5b2a..2a81c1e 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -1217,15 +1217,15 @@
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, result);
}
@@ -1446,14 +1446,19 @@
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, result);
}
@@ -1467,6 +1472,11 @@
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result);
}
+ JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallSetResult(operation, result);
+ }
JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, int32_t imm)
{
m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm))));
@@ -1722,14 +1732,14 @@
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), EABI_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EReoJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
+ JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3Payload, arg3Tag);
return appendCallSetResult(operation, resultPayload, resultTag);
}
- JITCompiler::Call callOperation(J_JITOperation_EReoJss operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, resultPayload, resultTag);
}
JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
@@ -1829,14 +1839,19 @@
m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
+ JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
+ m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3Payload, arg3Tag);
+ return appendCallSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, result);
}
JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
@@ -1844,6 +1859,11 @@
m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
return appendCallSetResult(operation, resultPayload, resultTag);
}
+ JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
+ return appendCallSetResult(operation, resultPayload, resultTag);
+ }
JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
{
m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag));
@@ -2309,6 +2329,7 @@
void compileGetScope(Node*);
void compileSkipScope(Node*);
+ void compileGetGlobalObject(Node*);
void compileGetArrayLength(Node*);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 3377c11..6ad47c1 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -2836,48 +2836,51 @@
}
case RegExpExec: {
- if (node->child1().useKind() == RegExpObjectUse) {
- if (node->child2().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child1());
- SpeculateCellOperand argument(this, node->child2());
+ SpeculateCellOperand globalObject(this, node->child1());
+ GPRReg globalObjectGPR = globalObject.gpr();
+
+ if (node->child2().useKind() == RegExpObjectUse) {
+ if (node->child3().useKind() == StringUse) {
+ SpeculateCellOperand base(this, node->child2());
+ SpeculateCellOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child1(), baseGPR);
- speculateString(node->child2(), argumentGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
+ speculateString(node->child3(), argumentGPR);
flushRegisters();
GPRFlushedCallResult2 resultTag(this);
GPRFlushedCallResult resultPayload(this);
callOperation(
- operationRegExpExecString, resultTag.gpr(), resultPayload.gpr(), baseGPR,
- argumentGPR);
+ operationRegExpExecString, resultTag.gpr(), resultPayload.gpr(),
+ globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ SpeculateCellOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentTagGPR = argument.tagGPR();
GPRReg argumentPayloadGPR = argument.payloadGPR();
- speculateRegExpObject(node->child1(), baseGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
flushRegisters();
GPRFlushedCallResult2 resultTag(this);
GPRFlushedCallResult resultPayload(this);
callOperation(
- operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), baseGPR, argumentTagGPR,
- argumentPayloadGPR);
+ operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), globalObjectGPR, baseGPR,
+ argumentTagGPR, argumentPayloadGPR);
m_jit.exceptionCheck();
jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
- JSValueOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ JSValueOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseTagGPR = base.tagGPR();
GPRReg basePayloadGPR = base.payloadGPR();
GPRReg argumentTagGPR = argument.tagGPR();
@@ -2886,7 +2889,9 @@
flushRegisters();
GPRFlushedCallResult2 resultTag(this);
GPRFlushedCallResult resultPayload(this);
- callOperation(operationRegExpExecGeneric, resultTag.gpr(), resultPayload.gpr(), baseTagGPR, basePayloadGPR, argumentTagGPR, argumentPayloadGPR);
+ callOperation(
+ operationRegExpExecGeneric, resultTag.gpr(), resultPayload.gpr(), globalObjectGPR,
+ baseTagGPR, basePayloadGPR, argumentTagGPR, argumentPayloadGPR);
m_jit.exceptionCheck();
jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
@@ -2894,43 +2899,48 @@
}
case RegExpTest: {
- if (node->child1().useKind() == RegExpObjectUse) {
- if (node->child2().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child1());
- SpeculateCellOperand argument(this, node->child2());
+ SpeculateCellOperand globalObject(this, node->child1());
+ GPRReg globalObjectGPR = globalObject.gpr();
+
+ if (node->child2().useKind() == RegExpObjectUse) {
+ if (node->child3().useKind() == StringUse) {
+ SpeculateCellOperand base(this, node->child2());
+ SpeculateCellOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child1(), baseGPR);
- speculateString(node->child2(), argumentGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
+ speculateString(node->child3(), argumentGPR);
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpTestString, result.gpr(), baseGPR, argumentGPR);
+ callOperation(
+ operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
booleanResult(result.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ SpeculateCellOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentTagGPR = argument.tagGPR();
GPRReg argumentPayloadGPR = argument.payloadGPR();
- speculateRegExpObject(node->child1(), baseGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
flushRegisters();
GPRFlushedCallResult result(this);
callOperation(
- operationRegExpTest, result.gpr(), baseGPR, argumentTagGPR, argumentPayloadGPR);
+ operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentTagGPR,
+ argumentPayloadGPR);
m_jit.exceptionCheck();
booleanResult(result.gpr(), node);
break;
}
- JSValueOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ JSValueOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseTagGPR = base.tagGPR();
GPRReg basePayloadGPR = base.payloadGPR();
GPRReg argumentTagGPR = argument.tagGPR();
@@ -2938,7 +2948,9 @@
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpTestGeneric, result.gpr(), baseTagGPR, basePayloadGPR, argumentTagGPR, argumentPayloadGPR);
+ callOperation(
+ operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseTagGPR, basePayloadGPR,
+ argumentTagGPR, argumentPayloadGPR);
m_jit.exceptionCheck();
booleanResult(result.gpr(), node);
@@ -3901,6 +3913,10 @@
compileSkipScope(node);
break;
+ case GetGlobalObject:
+ compileGetGlobalObject(node);
+ break;
+
case GetClosureVar: {
SpeculateCellOperand base(this, node->child1());
GPRTemporary resultTag(this);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 4e326be..51ba32c 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -2962,47 +2962,50 @@
}
case RegExpExec: {
- if (node->child1().useKind() == RegExpObjectUse) {
- if (node->child2().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child1());
- SpeculateCellOperand argument(this, node->child2());
+ SpeculateCellOperand globalObject(this, node->child1());
+ GPRReg globalObjectGPR = globalObject.gpr();
+
+ if (node->child2().useKind() == RegExpObjectUse) {
+ if (node->child3().useKind() == StringUse) {
+ SpeculateCellOperand base(this, node->child2());
+ SpeculateCellOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child1(), baseGPR);
- speculateString(node->child2(), argumentGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
+ speculateString(node->child3(), argumentGPR);
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpExecString, result.gpr(), baseGPR, argumentGPR);
+ callOperation(operationRegExpExecString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
jsValueResult(result.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ SpeculateCellOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child1(), baseGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpExec, result.gpr(), baseGPR, argumentGPR);
+ callOperation(operationRegExpExec, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
jsValueResult(result.gpr(), node);
break;
}
- JSValueOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ JSValueOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpExecGeneric, result.gpr(), baseGPR, argumentGPR);
+ callOperation(operationRegExpExecGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
jsValueResult(result.gpr(), node);
@@ -3010,18 +3013,21 @@
}
case RegExpTest: {
- if (node->child1().useKind() == RegExpObjectUse) {
- if (node->child2().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child1());
- SpeculateCellOperand argument(this, node->child2());
+ SpeculateCellOperand globalObject(this, node->child1());
+ GPRReg globalObjectGPR = globalObject.gpr();
+
+ if (node->child2().useKind() == RegExpObjectUse) {
+ if (node->child3().useKind() == StringUse) {
+ SpeculateCellOperand base(this, node->child2());
+ SpeculateCellOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child1(), baseGPR);
- speculateString(node->child2(), argumentGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
+ speculateString(node->child3(), argumentGPR);
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpTestString, result.gpr(), baseGPR, argumentGPR);
+ callOperation(operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
@@ -3029,15 +3035,15 @@
break;
}
- SpeculateCellOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ SpeculateCellOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child1(), baseGPR);
+ speculateRegExpObject(node->child2(), baseGPR);
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
+ callOperation(operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
@@ -3045,14 +3051,14 @@
break;
}
- JSValueOperand base(this, node->child1());
- JSValueOperand argument(this, node->child2());
+ JSValueOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationRegExpTestGeneric, result.gpr(), baseGPR, argumentGPR);
+ callOperation(operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
m_jit.exceptionCheck();
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
@@ -3930,6 +3936,10 @@
case SkipScope:
compileSkipScope(node);
break;
+
+ case GetGlobalObject:
+ compileGetGlobalObject(node);
+ break;
case GetClosureVar: {
SpeculateCellOperand base(this, node->child1());
diff --git a/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
index 2c05598..0081a10 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
@@ -149,7 +149,7 @@
case NewGeneratorFunction:
registerStructure(m_graph.globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
break;
-
+
default:
break;
}