haikuwebkit/LayoutTests/js/dfg-to-string-side-effect-c...

260 lines
12 KiB
Plaintext
Raw Permalink Normal View History

DFG string conversions and allocations should be inlined https://bugs.webkit.org/show_bug.cgi?id=112376 Source/JavaScriptCore: Reviewed by Geoffrey Garen. This turns new String(), String(), String.prototype.valueOf(), and String.prototype.toString() into intrinsics. It gives the DFG the ability to handle conversions from StringObject to JSString and vice-versa, and also gives it the ability to handle cases where a variable may be either a StringObject or a JSString. To do this, I added StringObject to value profiling (and removed the stale distinction between Myarguments and Foreignarguments). I also cleaned up ToPrimitive handling, using some of the new functionality but also taking advantage of the existence of Identity(String:@a). This is a 2% SunSpider speed-up. Also there are some speed-ups on V8v7 and Kraken. On microbenchmarks that stress new String() this is a 14x speed-up. * CMakeLists.txt: * DerivedSources.make: * DerivedSources.pri: * GNUmakefile.list.am: * bytecode/CodeBlock.h: (CodeBlock): (JSC::CodeBlock::hasExitSite): (JSC): * bytecode/DFGExitProfile.cpp: (JSC::DFG::ExitProfile::hasExitSite): (DFG): * bytecode/DFGExitProfile.h: (ExitProfile): (JSC::DFG::ExitProfile::hasExitSite): * bytecode/ExitKind.cpp: (JSC::exitKindToString): * bytecode/ExitKind.h: * bytecode/SpeculatedType.cpp: (JSC::dumpSpeculation): (JSC::speculationToAbbreviatedString): (JSC::speculationFromClassInfo): * bytecode/SpeculatedType.h: (JSC): (JSC::isStringObjectSpeculation): (JSC::isStringOrStringObjectSpeculation): * create_hash_table: * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::executeEffects): * dfg/DFGAbstractState.h: (JSC::DFG::AbstractState::filterEdgeByUse): * dfg/DFGByteCodeParser.cpp: (ByteCodeParser): (JSC::DFG::ByteCodeParser::handleCall): (JSC::DFG::ByteCodeParser::emitArgumentPhantoms): (DFG): (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): * dfg/DFGCSEPhase.cpp: (JSC::DFG::CSEPhase::putStructureStoreElimination): * dfg/DFGEdge.h: (JSC::DFG::Edge::shift): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::isStringPrototypeMethodSane): (FixupPhase): (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess): (JSC::DFG::FixupPhase::observeUseKindOnNode): * dfg/DFGGraph.h: (JSC::DFG::Graph::hasGlobalExitSite): (Graph): (JSC::DFG::Graph::hasExitSite): (JSC::DFG::Graph::clobbersWorld): * dfg/DFGNode.h: (JSC::DFG::Node::convertToToString): (Node): (JSC::DFG::Node::hasStructure): (JSC::DFG::Node::shouldSpeculateStringObject): (JSC::DFG::Node::shouldSpeculateStringOrStringObject): * dfg/DFGNodeType.h: (DFG): * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileToStringOnCell): (DFG): (JSC::DFG::SpeculativeJIT::compileNewStringObject): (JSC::DFG::SpeculativeJIT::speculateObject): (JSC::DFG::SpeculativeJIT::speculateObjectOrOther): (JSC::DFG::SpeculativeJIT::speculateString): (JSC::DFG::SpeculativeJIT::speculateStringObject): (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject): (JSC::DFG::SpeculativeJIT::speculate): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::callOperation): (SpeculativeJIT): (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand): (DFG): (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::fillSpeculateCell): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::fillSpeculateCell): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGUseKind.cpp: (WTF::printInternal): * dfg/DFGUseKind.h: (JSC::DFG::typeFilterFor): * interpreter/CallFrame.h: (JSC::ExecState::regExpPrototypeTable): * runtime/CommonIdentifiers.h: * runtime/Intrinsic.h: * runtime/JSDestructibleObject.h: (JSDestructibleObject): (JSC::JSDestructibleObject::classInfoOffset): * runtime/JSGlobalData.cpp: (JSC): (JSC::JSGlobalData::JSGlobalData): (JSC::JSGlobalData::~JSGlobalData): * runtime/JSGlobalData.h: (JSGlobalData): * runtime/JSObject.cpp: * runtime/JSObject.h: (JSC): * runtime/JSWrapperObject.h: (JSC::JSWrapperObject::allocationSize): (JSWrapperObject): (JSC::JSWrapperObject::internalValueOffset): (JSC::JSWrapperObject::internalValueCellOffset): * runtime/StringPrototype.cpp: (JSC): (JSC::StringPrototype::finishCreation): (JSC::StringPrototype::create): * runtime/StringPrototype.h: (StringPrototype): LayoutTests: Reviewed by Geoffrey Garen. * fast/js/dfg-to-string-bad-toString-expected.txt: Added. * fast/js/dfg-to-string-bad-toString.html: Added. * fast/js/dfg-to-string-bad-valueOf-expected.txt: Added. * fast/js/dfg-to-string-bad-valueOf.html: Added. * fast/js/dfg-to-string-int-expected.txt: Added. * fast/js/dfg-to-string-int-or-string-expected.txt: Added. * fast/js/dfg-to-string-int-or-string.html: Added. * fast/js/dfg-to-string-int.html: Added. * fast/js/dfg-to-string-side-effect-clobbers-toString-expected.txt: Added. * fast/js/dfg-to-string-side-effect-clobbers-toString.html: Added. * fast/js/dfg-to-string-side-effect-expected.txt: Added. * fast/js/dfg-to-string-side-effect.html: Added. * fast/js/dfg-to-string-toString-becomes-bad-expected.txt: Added. * fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype-expected.txt: Added. * fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.html: Added. * fast/js/dfg-to-string-toString-becomes-bad.html: Added. * fast/js/dfg-to-string-toString-in-string-expected.txt: Added. * fast/js/dfg-to-string-toString-in-string.html: Added. * fast/js/dfg-to-string-valueOf-becomes-bad-expected.txt: Added. * fast/js/dfg-to-string-valueOf-becomes-bad.html: Added. * fast/js/dfg-to-string-valueOf-in-string-expected.txt: Added. * fast/js/dfg-to-string-valueOf-in-string.html: Added. * fast/js/jsc-test-list: * fast/js/regress/script-tests/string-concat-object.js: Added. (foo): * fast/js/regress/script-tests/string-concat-pair-object.js: Added. (foo): * fast/js/regress/script-tests/string-concat-pair-simple.js: Added. (foo): * fast/js/regress/script-tests/string-concat-simple.js: Added. (foo): * fast/js/regress/script-tests/string-cons-repeat.js: Added. (foo): * fast/js/regress/script-tests/string-cons-tower.js: Added. (foo): * fast/js/regress/string-concat-object-expected.txt: Added. * fast/js/regress/string-concat-object.html: Added. * fast/js/regress/string-concat-pair-object-expected.txt: Added. * fast/js/regress/string-concat-pair-object.html: Added. * fast/js/regress/string-concat-pair-simple-expected.txt: Added. * fast/js/regress/string-concat-pair-simple.html: Added. * fast/js/regress/string-concat-simple-expected.txt: Added. * fast/js/regress/string-concat-simple.html: Added. * fast/js/regress/string-cons-repeat-expected.txt: Added. * fast/js/regress/string-cons-repeat.html: Added. * fast/js/regress/string-cons-tower-expected.txt: Added. * fast/js/regress/string-cons-tower.html: Added. * fast/js/script-tests/dfg-to-string-bad-toString.js: Added. (String.prototype.toString): (foo): * fast/js/script-tests/dfg-to-string-bad-valueOf.js: Added. (String.prototype.valueOf): (foo): * fast/js/script-tests/dfg-to-string-int-or-string.js: Added. (foo): * fast/js/script-tests/dfg-to-string-int.js: Added. (foo): * fast/js/script-tests/dfg-to-string-side-effect-clobbers-toString.js: Added. (foo): * fast/js/script-tests/dfg-to-string-side-effect.js: Added. (foo): * fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype.js: Added. (foo): (.String.prototype.toString): * fast/js/script-tests/dfg-to-string-toString-becomes-bad.js: Added. (foo): (.String.prototype.toString): * fast/js/script-tests/dfg-to-string-toString-in-string.js: Added. (foo): (.argument.toString): * fast/js/script-tests/dfg-to-string-valueOf-becomes-bad.js: Added. (foo): (.String.prototype.valueOf): * fast/js/script-tests/dfg-to-string-valueOf-in-string.js: Added. (foo): (.argument.valueOf): Canonical link: https://commits.webkit.org/130896@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@146089 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2013-03-18 18:09:22 +00:00
Tests what happens when you do ToString twice, and it has a side effect that clobbers the toString method in between the two ToStrings.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
PASS foo(new String("hello"), sideEffect) is "hellohello"
hi!
PASS foo(new String("hello"), sideEffect) is "hello150"
hi!
PASS foo(new String("hello"), sideEffect) is "hello151"
hi!
PASS foo(new String("hello"), sideEffect) is "hello152"
hi!
PASS foo(new String("hello"), sideEffect) is "hello153"
hi!
PASS foo(new String("hello"), sideEffect) is "hello154"
hi!
PASS foo(new String("hello"), sideEffect) is "hello155"
hi!
PASS foo(new String("hello"), sideEffect) is "hello156"
hi!
PASS foo(new String("hello"), sideEffect) is "hello157"
hi!
PASS foo(new String("hello"), sideEffect) is "hello158"
hi!
PASS foo(new String("hello"), sideEffect) is "hello159"
hi!
PASS foo(new String("hello"), sideEffect) is "hello160"
hi!
PASS foo(new String("hello"), sideEffect) is "hello161"
hi!
PASS foo(new String("hello"), sideEffect) is "hello162"
hi!
PASS foo(new String("hello"), sideEffect) is "hello163"
hi!
PASS foo(new String("hello"), sideEffect) is "hello164"
hi!
PASS foo(new String("hello"), sideEffect) is "hello165"
hi!
PASS foo(new String("hello"), sideEffect) is "hello166"
hi!
PASS foo(new String("hello"), sideEffect) is "hello167"
hi!
PASS foo(new String("hello"), sideEffect) is "hello168"
hi!
PASS foo(new String("hello"), sideEffect) is "hello169"
hi!
PASS foo(new String("hello"), sideEffect) is "hello170"
hi!
PASS foo(new String("hello"), sideEffect) is "hello171"
hi!
PASS foo(new String("hello"), sideEffect) is "hello172"
hi!
PASS foo(new String("hello"), sideEffect) is "hello173"
hi!
PASS foo(new String("hello"), sideEffect) is "hello174"
hi!
PASS foo(new String("hello"), sideEffect) is "hello175"
hi!
PASS foo(new String("hello"), sideEffect) is "hello176"
hi!
PASS foo(new String("hello"), sideEffect) is "hello177"
hi!
PASS foo(new String("hello"), sideEffect) is "hello178"
hi!
PASS foo(new String("hello"), sideEffect) is "hello179"
hi!
PASS foo(new String("hello"), sideEffect) is "hello180"
hi!
PASS foo(new String("hello"), sideEffect) is "hello181"
hi!
PASS foo(new String("hello"), sideEffect) is "hello182"
hi!
PASS foo(new String("hello"), sideEffect) is "hello183"
hi!
PASS foo(new String("hello"), sideEffect) is "hello184"
hi!
PASS foo(new String("hello"), sideEffect) is "hello185"
hi!
PASS foo(new String("hello"), sideEffect) is "hello186"
hi!
PASS foo(new String("hello"), sideEffect) is "hello187"
hi!
PASS foo(new String("hello"), sideEffect) is "hello188"
hi!
PASS foo(new String("hello"), sideEffect) is "hello189"
hi!
PASS foo(new String("hello"), sideEffect) is "hello190"
hi!
PASS foo(new String("hello"), sideEffect) is "hello191"
hi!
PASS foo(new String("hello"), sideEffect) is "hello192"
hi!
PASS foo(new String("hello"), sideEffect) is "hello193"
hi!
PASS foo(new String("hello"), sideEffect) is "hello194"
hi!
PASS foo(new String("hello"), sideEffect) is "hello195"
hi!
PASS foo(new String("hello"), sideEffect) is "hello196"
hi!
PASS foo(new String("hello"), sideEffect) is "hello197"
hi!
PASS foo(new String("hello"), sideEffect) is "hello198"
hi!
PASS foo(new String("hello"), sideEffect) is "hello199"
PASS successfullyParsed is true
TEST COMPLETE