| 2016-10-04 Yusuke Suzuki <utatane.tea@gmail.com> |
| |
| [DOMJIT] Introduce DOMJIT::GetterSetter to tell JIT information |
| https://bugs.webkit.org/show_bug.cgi?id=162916 |
| |
| Reviewed by Filip Pizlo. |
| |
| In this patch, we introduce DOMJIT::GetterSetter. |
| This class maintains information required to emit JIT code in DFG and FTL. |
| DOMJIT::GetterSetter has 2 virtual functions: checkDOM and callDOM. |
| These functions can return a DOMJIT::Patchpoint that allows us to inject |
| appropriate machine code during DFG and FTL phases. DFG and FTL will invoke |
| these functions to get a patchpoint. And this patchpoint will be used to |
| emit code corresponding to CheckDOM and CallDOM DFG nodes, which will be added |
| in subsqeunt patch. |
| |
| We propagate DOMJIT::GetterSetter through PropertySlot, AccessCase, GetByIdVariant, |
| and GetByIdStatus along with CustomGetter to teach DFG that this custom access |
| code has a chance to be inlined with this DOMJIT::GetterSetter information. |
| Instead of propagating CustomGetterSetter holding DOMJIT::GetterSetter and CustomGetter, |
| we propagate CustomGetter and DOMJIT::GetterSetter. This is because of the current |
| CustomGetterSetter design that we reify CustomGetterSetters only when we need to reify |
| all the properties. This design allows us to avoid frequent CustomGetterSetter allocations |
| and structure transitions. |
| |
| Currently, domJIT field is always nullptr since there is no DOMJITAttribute user. |
| When we add this, we will add code handling this DOMJIT::GetterSetter in DFG::ByteCodeParser. |
| |
| * CMakeLists.txt: |
| * JavaScriptCore.xcodeproj/project.pbxproj: |
| * bytecode/GetByIdStatus.cpp: |
| (JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback): |
| * bytecode/GetByIdVariant.cpp: |
| (JSC::GetByIdVariant::GetByIdVariant): |
| (JSC::GetByIdVariant::operator=): |
| (JSC::GetByIdVariant::attemptToMerge): |
| (JSC::GetByIdVariant::dumpInContext): |
| * bytecode/GetByIdVariant.h: |
| (JSC::GetByIdVariant::domJIT): |
| (JSC::GetByIdVariant::intrinsic): Deleted. |
| * bytecode/PolymorphicAccess.cpp: |
| (JSC::AccessCase::get): |
| (JSC::AccessCase::clone): |
| * bytecode/PolymorphicAccess.h: |
| (JSC::AccessCase::domJIT): |
| (JSC::AccessCase::RareData::RareData): |
| * dfg/DFGNode.h: |
| * domjit/DOMJITGetterSetter.h: Added. |
| (JSC::DOMJIT::GetterSetter::GetterSetter): |
| (JSC::DOMJIT::GetterSetter::~GetterSetter): |
| (JSC::DOMJIT::GetterSetter::getter): |
| (JSC::DOMJIT::GetterSetter::setter): |
| (JSC::DOMJIT::GetterSetter::thisClassInfo): |
| * domjit/DOMJITPatchpoint.h: Added. |
| (JSC::DOMJIT::Patchpoint::create): |
| (JSC::DOMJIT::Patchpoint::setGenerator): |
| (JSC::DOMJIT::Patchpoint::generator): |
| * jit/Repatch.cpp: |
| (JSC::tryCacheGetByID): |
| * runtime/CustomGetterSetter.h: |
| * runtime/JSObject.h: |
| (JSC::JSObject::fillCustomGetterPropertySlot): |
| * runtime/Lookup.h: |
| (JSC::HashTableValue::domJIT): |
| (JSC::getStaticPropertySlotFromTable): |
| (JSC::putEntry): |
| (JSC::reifyStaticProperty): |
| * runtime/PropertySlot.h: |
| (JSC::PropertySlot::domJIT): |
| (JSC::PropertySlot::setCacheableCustom): |
| |
| 2016-09-27 Yusuke Suzuki <utatane.tea@gmail.com> |
| |
| [JSC] Add a new byte code op_define_property instead of calling defineProperty |
| https://bugs.webkit.org/show_bug.cgi?id=162108 |
| |
| Reviewed by Saam Barati. |
| |
| To construct ES6 class, we emitted bytecode that performs the following operations. |
| |
| 1. construct a new object |
| 2. put "configurable", "enumerable" etc. fields |
| 3. call "defineProperty" function |
| |
| However, this approach has problems. Every time we define a class method, we need to create |
| a new object to represent property descriptor. This can be removed if we can introduce |
| a special bytecode or special function. |
| |
| This patch introduces new bytecodes, op_define_data_property and op_define_accessor_property. |
| Instead of taking an object, they takes several registers to avoid object allocations. |
| We're planning to use this bytecode to implement Object.defineProperty in builtin JS next. |
| This allows us to leverage object allocation sinking. And it also gives us a chance to use |
| faster ::get and ::hasProperty in JS. |
| |
| Originally, I attempted to create one bytecode, op_define_property. However, it takes too many |
| children in DFG and uses so many registers in DFG. This leads tricky program in 32bit platforms. |
| Furthermore, it does not fit to the number of x64 argument registers. So instead, we introduce |
| two bytecodes. |
| |
| And for op_define_accessor_property, we perform CellUse edge filter to getter and setter children. |
| This edge filter makes us possible to use SpeculateCellOperand and reduce the number of used registers |
| in comparison with JSValueOperand. To make children Cells even if we do not specify some accessors (for |
| example, { get: func, set: null } case), we fill registers with special throwTypeErrorFunction. |
| The attributes bitset keep information like "This property descriptor only has getter slot". |
| |
| In these two bytecodes, we take attributes (configurable, enumerable, writable, hasGetter etc.) as |
| register instead of embedding constant int value because we will use these bytecodes to implement |
| Object.defineProperty next. In Object.defineProperty case, an attributes are not statically defined |
| at bytecode compiling time. |
| |
| Run ES6SampleBench/Air 20 times. The result shows ~2% performance improvement. |
| |
| Baseline: |
| firstIteration: 84.05 ms +- 4.37 ms |
| averageWorstCase: 40.54 ms +- 2.81 ms |
| steadyState: 3317.49 ms +- 48.25 ms |
| summary: 223.51 ms +- 5.07 ms |
| |
| Patched: |
| firstIteration: 84.46 ms +- 4.22 ms |
| averageWorstCase: 41.48 ms +- 2.33 ms |
| steadyState: 3253.48 ms +- 29.31 ms |
| summary: 224.40 ms +- 4.72 ms |
| |
| * JavaScriptCore.xcodeproj/project.pbxproj: |
| * bytecode/BytecodeList.json: |
| * bytecode/BytecodeUseDef.h: |
| (JSC::computeUsesForBytecodeOffset): |
| (JSC::computeDefsForBytecodeOffset): |
| * bytecode/CodeBlock.cpp: |
| (JSC::CodeBlock::dumpBytecode): |
| * bytecode/SpecialPointer.h: |
| * bytecompiler/BytecodeGenerator.cpp: |
| (JSC::BytecodeGenerator::emitMoveLinkTimeConstant): |
| (JSC::BytecodeGenerator::emitCallDefineProperty): |
| * bytecompiler/BytecodeGenerator.h: |
| * bytecompiler/NodesCodegen.cpp: |
| (JSC::PropertyListNode::emitPutConstantProperty): |
| (JSC::BitwiseNotNode::emitBytecode): |
| (JSC::ClassExprNode::emitBytecode): |
| (JSC::ObjectPatternNode::bindValue): |
| * dfg/DFGAbstractInterpreterInlines.h: |
| (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): |
| * dfg/DFGByteCodeParser.cpp: |
| (JSC::DFG::ByteCodeParser::parseBlock): |
| * dfg/DFGCapabilities.cpp: |
| (JSC::DFG::capabilityLevel): |
| * 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: |
| * dfg/DFGSafeToExecute.h: |
| (JSC::DFG::safeToExecute): |
| * dfg/DFGSpeculativeJIT.cpp: |
| (JSC::DFG::SpeculativeJIT::compileDefineDataProperty): |
| (JSC::DFG::SpeculativeJIT::compileDefineAccessorProperty): |
| * 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::compileDefineDataProperty): |
| (JSC::FTL::DFG::LowerDFGToB3::compileDefineAccessorProperty): |
| (JSC::FTL::DFG::LowerDFGToB3::compilePutByValWithThis): Deleted. |
| * jit/CCallHelpers.cpp: |
| (JSC::CCallHelpers::setupFourStubArgsGPR): Deleted. |
| * jit/CCallHelpers.h: |
| (JSC::CCallHelpers::setupFourStubArgsGPR): |
| (JSC::CCallHelpers::setupFiveStubArgsGPR): |
| (JSC::CCallHelpers::setupArgumentsWithExecState): |
| (JSC::CCallHelpers::setupStubArgsGPR): |
| (JSC::CCallHelpers::prepareForTailCallSlow): Deleted. |
| * jit/JIT.cpp: |
| (JSC::JIT::privateCompileMainPass): |
| * jit/JIT.h: |
| * jit/JITOperations.h: |
| * jit/JITPropertyAccess.cpp: |
| (JSC::JIT::emit_op_define_data_property): |
| (JSC::JIT::emit_op_define_accessor_property): |
| * llint/LowLevelInterpreter.asm: |
| * runtime/CommonSlowPaths.cpp: |
| (JSC::SLOW_PATH_DECL): |
| * runtime/CommonSlowPaths.h: |
| * runtime/DefinePropertyAttributes.h: Added. |
| (JSC::DefinePropertyAttributes::DefinePropertyAttributes): |
| (JSC::DefinePropertyAttributes::rawRepresentation): |
| (JSC::DefinePropertyAttributes::hasValue): |
| (JSC::DefinePropertyAttributes::setValue): |
| (JSC::DefinePropertyAttributes::hasGet): |
| (JSC::DefinePropertyAttributes::setGet): |
| (JSC::DefinePropertyAttributes::hasSet): |
| (JSC::DefinePropertyAttributes::setSet): |
| (JSC::DefinePropertyAttributes::writable): |
| (JSC::DefinePropertyAttributes::configurable): |
| (JSC::DefinePropertyAttributes::enumerable): |
| (JSC::DefinePropertyAttributes::setWritable): |
| (JSC::DefinePropertyAttributes::setConfigurable): |
| (JSC::DefinePropertyAttributes::setEnumerable): |
| (JSC::DefinePropertyAttributes::fillWithTriState): |
| (JSC::DefinePropertyAttributes::extractTriState): |
| * runtime/JSGlobalObject.cpp: |
| (JSC::JSGlobalObject::init): |
| (JSC::JSGlobalObject::visitChildren): |
| * runtime/JSGlobalObject.h: |
| (JSC::JSGlobalObject::throwTypeErrorFunction): |
| (JSC::JSGlobalObject::definePropertyFunction): Deleted. |
| * runtime/ObjectConstructor.cpp: |
| (JSC::ObjectConstructor::addDefineProperty): Deleted. |
| * runtime/ObjectConstructor.h: |
| * runtime/PropertyDescriptor.h: |
| (JSC::toPropertyDescriptor): |
| |
| 2016-10-04 Saam Barati <sbarati@apple.com> |
| |
| Follow up fix to GetMapBucket and MapHash speculating on child node types. |
| To fix this, on 32-bit platforms, we do not speculate on the child |
| type since we just call into C code for these nodes. |
| |
| * dfg/DFGFixupPhase.cpp: |
| (JSC::DFG::FixupPhase::fixupNode): |
| |
| 2016-10-03 Saam Barati <sbarati@apple.com> |
| |
| GetMapBucket node should speculate on the type of its 'key' child |
| https://bugs.webkit.org/show_bug.cgi?id=161638 |
| |
| Reviewed by Filip Pizlo. |
| |
| This eliminates type-check branches when we've already |
| proven the type of the incoming key. Also, it reduces |
| the branches we emit when type checking the bucket's key. |
| |
| This is a 2-3% speedup on ES6SampleBench/Basic. |
| |
| * dfg/DFGFixupPhase.cpp: |
| (JSC::DFG::FixupPhase::fixupNode): |
| * dfg/DFGSpeculativeJIT64.cpp: |
| (JSC::DFG::SpeculativeJIT::compile): |
| * ftl/FTLLowerDFGToB3.cpp: |
| (JSC::FTL::DFG::LowerDFGToB3::compileGetMapBucket): |
| |
| 2016-10-03 Christopher Reid <Christopher.Reid@am.sony.com> |
| |
| Offline asm should not output masm assembly when using a x86_64 asm backend |
| https://bugs.webkit.org/show_bug.cgi?id=162705 |
| |
| When cross compiling on windows to Clang, masm was being generated simply because |
| the os was windows. This change adds a command line parameter --assembler=MASM |
| to set the output assembly to masm. |
| The functions isGCC and isCompilingToWindows were removed as they are no longer called. |
| |
| Reviewed by Mark Lam. |
| |
| * CMakeLists.txt: |
| * offlineasm/asm.rb: |
| * offlineasm/x86.rb: |
| |
| 2016-10-03 JF Bastien <jfbastien@apple.com> |
| |
| Auto-generate WASMOps.h, share with testing JSON file |
| https://bugs.webkit.org/show_bug.cgi?id=162870 |
| |
| Reviewed by Keith Miller. |
| |
| Add a few new opcodes, but keep this mostly as-is for now. I want |
| to generate smarter code but will do so in a later update to |
| reduce disruption. |
| |
| * wasm/WASMOps.h: auto-generated from ./JSTests/stress/wasm/to-c++.js |
| |
| 2016-10-03 Michael Saboff <msaboff@apple.com> |
| |
| Creating pcToOriginMap in FTL shouldn't insert unnecessary NOPs |
| https://bugs.webkit.org/show_bug.cgi?id=162879 |
| |
| Reviewed by Filip Pizlo. |
| |
| If there is a recent watchpoint label, using MacroAssembler::label() will pad |
| the instruction stream with NOPs to provide space for a jump. This changes |
| Air::generate() to use labelIgnoringWatchpoints() to create pcToOriginMap |
| entries to eliminate unneccesary NOPs. |
| |
| * b3/air/AirGenerate.cpp: |
| (JSC::B3::Air::generate): |
| * b3/testb3.cpp: |
| (JSC::B3::testPCOriginMapDoesntInsertNops): New test. |
| (JSC::B3::run): |
| |
| 2016-10-03 Saam Barati <sbarati@apple.com> |
| |
| MapHash should speculate on the type of its child node |
| https://bugs.webkit.org/show_bug.cgi?id=161922 |
| |
| Reviewed by Filip Pizlo. |
| |
| This allows us to remove runtime type checks when we've already |
| proven the type of the incoming value. |
| |
| This is a 2-3% speedup on ES6SampleBench/Basic. |
| |
| * dfg/DFGFixupPhase.cpp: |
| (JSC::DFG::FixupPhase::fixupNode): |
| * dfg/DFGSpeculativeJIT64.cpp: |
| (JSC::DFG::SpeculativeJIT::compile): |
| * ftl/FTLLowerDFGToB3.cpp: |
| (JSC::FTL::DFG::LowerDFGToB3::wangsInt64Hash): |
| (JSC::FTL::DFG::LowerDFGToB3::mapHashString): |
| (JSC::FTL::DFG::LowerDFGToB3::compileMapHash): |
| |
| 2016-10-03 Filip Pizlo <fpizlo@apple.com> |
| |
| B3 trapping memory accesses should be documented |
| https://bugs.webkit.org/show_bug.cgi?id=162845 |
| |
| Reviewed by Geoffrey Garen. |
| |
| While writing some documentation, I found some small holes in the code. |
| |
| * b3/B3Effects.cpp: |
| (JSC::B3::Effects::operator==): Need this to write tests. |
| (JSC::B3::Effects::operator!=): Need this to write tests. |
| * b3/B3Effects.h: |
| * b3/B3HeapRange.h: |
| * b3/B3MemoryValue.cpp: |
| (JSC::B3::MemoryValue::dumpMeta): Sometimes the heap range dump won't show you the memory value's actual range. This makes the dump show you the actual range in that case. |
| * b3/B3Value.cpp: |
| (JSC::B3::Value::effects): While documenting this, I remembered that trapping also has to imply reading top. I fixed this. |
| * b3/testb3.cpp: |
| (JSC::B3::testTrappingLoad): Added checks for the effects of trapping loads. |
| (JSC::B3::testTrappingStore): Added checks for the effects of trapping stores. |
| (JSC::B3::testMoveConstants): Made this not crash with validation. |
| |
| 2016-10-03 Yusuke Suzuki <utatane.tea@gmail.com> |
| |
| [ES6] GeneratorFunction (a.k.a. GeneratorWrapperFunction)'s prototype object does not have constructor property |
| https://bugs.webkit.org/show_bug.cgi?id=162849 |
| |
| Reviewed by Geoffrey Garen. |
| |
| Since GeneratorFunction is not constructible, GeneratorFunction.prototype does not have "constructor" property. |
| |
| function* generatorFunction() { } |
| generatorFunction.prototype.constructor // undefined |
| |
| * runtime/JSFunction.cpp: |
| (JSC::JSFunction::getOwnPropertySlot): |
| |
| 2016-10-03 Nicolas Breidinger <Nicolas.Breidinger@sony.com> |
| |
| JSStringRef should define JSChar without platform checks |
| https://bugs.webkit.org/show_bug.cgi?id=162808 |
| |
| Reviewed by Mark Lam. |
| |
| * API/JSStringRef.h: |
| |
| 2016-10-01 Yusuke Suzuki <utatane.tea@gmail.com> |
| |
| [ES6] Align attributes of Generator related properties to spec |
| https://bugs.webkit.org/show_bug.cgi?id=162839 |
| |
| Reviewed by Saam Barati. |
| |
| This patch fixes attributes of Generator related properties. |
| These fixes are covered by test262. |
| |
| * runtime/GeneratorFunctionConstructor.cpp: |
| (JSC::GeneratorFunctionConstructor::finishCreation): |
| * runtime/GeneratorFunctionConstructor.h: |
| * runtime/GeneratorFunctionPrototype.cpp: |
| (JSC::GeneratorFunctionPrototype::finishCreation): |
| * runtime/GeneratorFunctionPrototype.h: |
| * runtime/GeneratorPrototype.h: |
| * runtime/JSGlobalObject.cpp: |
| (JSC::JSGlobalObject::init): |
| |
| 2016-10-01 Yusuke Suzuki <utatane.tea@gmail.com> |
| |
| [ES6] GeneratorFunction constructor should instantiate generator function |
| https://bugs.webkit.org/show_bug.cgi?id=162838 |
| |
| Reviewed by Saam Barati. |
| |
| GeneratorFunction's constructor should return an instance of JSGeneratorFunction |
| instead of JSFunction. In this patch, we fix the following 2 things. |
| |
| 1. GeneratorFunction constructor should use JSGeneratorFunction |
| |
| Previously, we used JSFunction to construct a result. It's wrong. We use JSGeneratorFunction. |
| |
| 2. Pass newTarget into GeneratorFunction constructor to make it subclassible |
| |
| We did not leverage newTarget when using GeneratorFunction constructor. |
| Using it correctly to create the subclass Structure and making GeneratorFunction subclassible. |
| |
| Test262 test covers (1), but (2) is not covered. We add tests that covers both to stress tests. |
| |
| * runtime/FunctionConstructor.cpp: |
| (JSC::constructFunctionSkippingEvalEnabledCheck): |
| * runtime/GeneratorFunctionConstructor.cpp: |
| (JSC::constructGeneratorFunctionConstructor): |
| * runtime/JSGeneratorFunction.cpp: |
| (JSC::JSGeneratorFunction::JSGeneratorFunction): |
| (JSC::JSGeneratorFunction::createImpl): |
| (JSC::JSGeneratorFunction::create): |
| (JSC::JSGeneratorFunction::createWithInvalidatedReallocationWatchpoint): |
| * runtime/JSGeneratorFunction.h: |
| |
| 2016-10-01 Filip Pizlo <fpizlo@apple.com> |
| |
| Get rid of isMarkedOrNewlyAllocated |
| https://bugs.webkit.org/show_bug.cgi?id=162842 |
| |
| Reviewed by Dan Bernstein. |
| |
| This function has become dead code. This change removes it. |
| |
| * heap/CellContainer.h: |
| * heap/CellContainerInlines.h: |
| (JSC::CellContainer::isMarkedOrNewlyAllocated): Deleted. |
| * heap/LargeAllocation.h: |
| (JSC::LargeAllocation::isLive): |
| (JSC::LargeAllocation::isMarkedOrNewlyAllocated): Deleted. |
| * heap/MarkedBlock.cpp: |
| (JSC::MarkedBlock::Handle::isMarkedOrNewlyAllocated): Deleted. |
| (JSC::MarkedBlock::isMarkedOrNewlyAllocated): Deleted. |
| * heap/MarkedBlock.h: |
| (JSC::MarkedBlock::Handle::isMarkedOrNewlyAllocated): Deleted. |
| (JSC::MarkedBlock::isMarkedOrNewlyAllocated): Deleted. |
| |
| 2016-10-01 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Rename DebugHookID to DebugHookType |
| https://bugs.webkit.org/show_bug.cgi?id=162820 |
| |
| Reviewed by Alex Christensen. |
| |
| * bytecode/CodeBlock.cpp: |
| (JSC::debugHookName): |
| (JSC::CodeBlock::dumpBytecode): |
| * bytecompiler/BytecodeGenerator.cpp: |
| (JSC::BytecodeGenerator::emitDebugHook): |
| * bytecompiler/BytecodeGenerator.h: |
| * interpreter/Interpreter.cpp: |
| (JSC::Interpreter::debug): |
| * interpreter/Interpreter.h: |
| * jit/JITOperations.cpp: |
| * llint/LLIntSlowPaths.cpp: |
| (JSC::LLInt::LLINT_SLOW_PATH_DECL): |
| |
| 2016-09-30 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Web Inspector: Stepping to a line with an autoContinue breakpoint should still pause |
| https://bugs.webkit.org/show_bug.cgi?id=161712 |
| <rdar://problem/28193970> |
| |
| Reviewed by Brian Burg. |
| |
| * debugger/Debugger.cpp: |
| (JSC::Debugger::pauseIfNeeded): |
| If we stepped to an auto-continue breakpoint we should continue |
| stepping, not just continue. |
| |
| 2016-09-30 Filip Pizlo <fpizlo@apple.com> |
| |
| B3 should support trapping memory accesses |
| https://bugs.webkit.org/show_bug.cgi?id=162689 |
| |
| Reviewed by Geoffrey Garen. |
| |
| This adds a traps flag to B3::Kind. It also makes B3::Kind work more like Air::Kind, in the |
| sense that it's a bag of distinct bits - it doesn't need to be a union unless we get enough |
| things that it would make a difference. |
| |
| The only analysis that needs to know about traps is effects. It now knows that traps implies |
| sideExits, which means that this turns off DCE. The only optimization that needs to know |
| about traps is eliminateCommonSubexpressions(), which needs to pessimize its store |
| elimination if the store traps. |
| |
| The hard part of this change is teaching the instruction selector to faithfully carry the |
| traps flag down to Air. I got this to work by making ArgPromise a non-copyable object that |
| knows whether you've used it in an instruction. It knows when you call consume(). If you do |
| this then ArgPromise cannot be destructed without first passing your inst through it. This, |
| along with a few other hacks, means that all of the load-op and load-op-store fusions |
| correctly carry the trap bit: if any of the B3 loads or stores involved traps then you get |
| traps in Air. |
| |
| This framework also sets us up to do bug 162688, since the ArgPromise::inst() hook is |
| powerful enough to allow wrapping the instruction with a Patch. |
| |
| I added some tests to testb3 that verify that optimizations are appropriately inhibited and |
| that the traps flag survives until the bitter end of Air. |
| |
| * b3/B3EliminateCommonSubexpressions.cpp: |
| * b3/B3Kind.cpp: |
| (JSC::B3::Kind::dump): |
| * b3/B3Kind.h: |
| (JSC::B3::Kind::Kind): |
| (JSC::B3::Kind::hasExtraBits): |
| (JSC::B3::Kind::isChill): |
| (JSC::B3::Kind::setIsChill): |
| (JSC::B3::Kind::hasTraps): |
| (JSC::B3::Kind::traps): |
| (JSC::B3::Kind::setTraps): |
| (JSC::B3::Kind::operator==): |
| (JSC::B3::Kind::hash): |
| (JSC::B3::trapping): |
| * b3/B3LowerToAir.cpp: |
| (JSC::B3::Air::LowerToAir::ArgPromise::swap): |
| (JSC::B3::Air::LowerToAir::ArgPromise::ArgPromise): |
| (JSC::B3::Air::LowerToAir::ArgPromise::operator=): |
| (JSC::B3::Air::LowerToAir::ArgPromise::~ArgPromise): |
| (JSC::B3::Air::LowerToAir::ArgPromise::setTraps): |
| (JSC::B3::Air::LowerToAir::ArgPromise::consume): |
| (JSC::B3::Air::LowerToAir::ArgPromise::inst): |
| (JSC::B3::Air::LowerToAir::trappingInst): |
| (JSC::B3::Air::LowerToAir::loadPromiseAnyOpcode): |
| (JSC::B3::Air::LowerToAir::appendUnOp): |
| (JSC::B3::Air::LowerToAir::appendBinOp): |
| (JSC::B3::Air::LowerToAir::tryAppendStoreUnOp): |
| (JSC::B3::Air::LowerToAir::tryAppendStoreBinOp): |
| (JSC::B3::Air::LowerToAir::appendStore): |
| (JSC::B3::Air::LowerToAir::append): |
| (JSC::B3::Air::LowerToAir::createGenericCompare): |
| (JSC::B3::Air::LowerToAir::createBranch): |
| (JSC::B3::Air::LowerToAir::createCompare): |
| (JSC::B3::Air::LowerToAir::createSelect): |
| (JSC::B3::Air::LowerToAir::lower): |
| * b3/B3Validate.cpp: |
| * b3/B3Value.cpp: |
| (JSC::B3::Value::effects): |
| * b3/B3Value.h: |
| * b3/air/AirCode.h: |
| * b3/testb3.cpp: |
| (JSC::B3::testTrappingLoad): |
| (JSC::B3::testTrappingStore): |
| (JSC::B3::testTrappingLoadAddStore): |
| (JSC::B3::testTrappingLoadDCE): |
| (JSC::B3::testTrappingStoreElimination): |
| (JSC::B3::run): |
| |
| 2016-09-30 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Web Inspector: Stepping over/out of a function sometimes resumes instead of taking you to caller |
| https://bugs.webkit.org/show_bug.cgi?id=162802 |
| <rdar://problem/28569982> |
| |
| Reviewed by Mark Lam. |
| |
| * debugger/Debugger.cpp: |
| (JSC::Debugger::stepOverStatement): |
| (JSC::Debugger::stepOutOfFunction): |
| Enable stepping mode when we start stepping. |
| |
| 2016-09-30 Filip Pizlo <fpizlo@apple.com> |
| |
| B3::moveConstants should be able to edit code to minimize the number of constants |
| https://bugs.webkit.org/show_bug.cgi?id=162764 |
| |
| Reviewed by Saam Barati. |
| |
| There are some interesting cases where we can reduce the number of constant materializations if |
| we teach moveConstants() how to edit code. The two examples that this patch supports are: |
| |
| - Loads and stores from a constant pointer. Since loads and stores get an offset for free |
| and the instruction selector is really good at handling it, and since we can query Air to |
| see what kinds of offsets are legal, we can sometimes avoid using a constant pointer that |
| is specific to the absolute address of that load and instead pick some other constant |
| that is within offset distance of ours. |
| |
| - Add and Sub by a constant (x + c, x - c). Since x + c = x - -c and x - c = x + -c, we can |
| flip Add to Sub or vice versa if the negated constant is available. |
| |
| This change makes moveConstants() pick the most dominant constant that works for an value. In |
| the case of memory accesses, it uses Air::Arg::isValidAddrForm() to work out what other |
| constants would work. In the case of Add/Sub, it simply looks for the negated constant. This |
| should result in something like a minimal number of constants since these rules always pick the |
| most dominant constant that works - so if an Add's constant is already most dominant then |
| nothing changes, but if the negated one is more dominant then it becomes a Sub. |
| |
| This is a 0.5% speed-up on LongSpider and neutral elsewhere. It's a speed-up because the |
| absolute address thing reduces the number of address materializations that we have to do, while |
| the add/sub thing prevents us from having to materialize 0x1000000000000 to box doubles. |
| However, this may introduce a pathology, which I've filed a bug for: bug 162796. |
| |
| * b3/B3MoveConstants.cpp: |
| * b3/B3MoveConstants.h: |
| * b3/B3UseCounts.h: |
| * b3/air/AirFixObviousSpills.cpp: |
| * b3/testb3.cpp: |
| (JSC::B3::testMoveConstants): |
| (JSC::B3::run): |
| |
| 2016-09-30 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Fix modules tests after r206653 handle breakpoint locations in import/export statements |
| https://bugs.webkit.org/show_bug.cgi?id=162807 |
| |
| Reviewed by Mark Lam. |
| |
| * parser/ASTBuilder.h: |
| (JSC::ASTBuilder::createExportDefaultDeclaration): |
| (JSC::ASTBuilder::createExportLocalDeclaration): |
| Don't record an extra breakpoint location for the statement |
| within an export statement. |
| |
| * parser/Parser.cpp: |
| (JSC::Parser<LexerType>::parseModuleSourceElements): |
| Record a pause location for import/export statements. |
| |
| 2016-09-30 Mark Lam <mark.lam@apple.com> |
| |
| Remove the dumping of the stack back trace in VM::verifyExceptionCheckNeedIsSatisfied(). |
| https://bugs.webkit.org/show_bug.cgi?id=162797 |
| |
| Reviewed by Geoffrey Garen. |
| |
| This is because the RELEASE_ASSERT() that follows immediately after will also |
| dump the stack back trace. Hence, the first dump will be redundant. |
| |
| Also removed an extra space in the dataLog output. |
| |
| * runtime/VM.cpp: |
| (JSC::VM::verifyExceptionCheckNeedIsSatisfied): |
| |
| 2016-09-30 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Web Inspector: Stepping through `a(); b(); c();` it is unclear where we are and what is about to execute |
| https://bugs.webkit.org/show_bug.cgi?id=161658 |
| <rdar://problem/28181254> |
| |
| Reviewed by Geoffrey Garen. |
| |
| * parser/Parser.cpp: |
| (JSC::Parser<LexerType>::parseAssignmentExpression): |
| Updated pause location for unary expressions. |
| |
| 2016-09-30 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Breakpoints on blank lines or comments don't break |
| https://bugs.webkit.org/show_bug.cgi?id=9885 |
| <rdar://problem/6134406> |
| |
| Reviewed by Mark Lam. |
| |
| This change introduces a way to perform a Debugger Parse of a script. |
| This debugger parse gathers a list of breakpoint locations, which |
| the backend uses to resolve breakpoint locations that came from the |
| Inspector frontend to the exact location we would actually pause. |
| We gather this information from the parser so that we can eagerly |
| get this information without requiring the code to have executed (the |
| real op_debugs are generated during bytecode generation when code |
| is actually evaluated). |
| |
| If an input location was on a line with whitespace or a comment, the |
| resolved breakpoint location would be before the next statement that |
| will be executed. That may be the next line, or even later. We also |
| update our policy when setting breakpoints on and around function |
| statements to better match user expectations. |
| |
| For example, when resolving breakpoints in: |
| |
| 1. // Comment |
| 2. before; |
| 3. |
| 4. function foo() { |
| 5. inside; |
| 6. } |
| 7. |
| 8. after; |
| |
| A breakpoint on line 1, a comment, resolves to line 2 the next |
| statement that will execute. |
| |
| A breakpoint on line 3 or 7, empty lines, resolves to line 8 the next |
| statement that will execute. This skips past the definition of foo, |
| just like stepping would have done. The creation of foo would have |
| been hoisted, which would have happened before execution of the |
| other statements. |
| |
| A breakpoint on line 4, a function signature, resolves to line 5, |
| inside the function. Users would expect to pause inside of a function |
| when setting a breakpoint on that function's name or opening brace. |
| |
| A breakpoint on line 6, a function's closing brace, resolves to |
| line 6. The debugger will pause whenever execution leaves foo due to |
| a return and not an exception. This matches stepping behavior. An |
| explicit or implicit return (the implicit return undefined) will |
| pause on the closing brace as we leave the function, giving users |
| an opportunity to inspect the final state before leaving. |
| |
| -- |
| |
| At this point, op_debug's are still emitted at custom locations during |
| bytecode generation of other statements / expressions. In order to |
| ensure the generated op_debugs correspond to locations the Parser |
| determined were breakpoint locations, the Parser sets a "needs debug |
| hook" flag on the nodes it will use for breakpoint locations, and |
| we assert during bytecode generation that op_debugs are only emitted |
| for nodes that were marked as needing debug hooks. |
| |
| This still leaves open the possibility that the Parser will mark |
| some nodes that get missed during bytecode generation, so we might |
| fail to emit some op_debugs. The next step will be eliminating the |
| custom emitDebugHooks spread across StatementNode and ExpressionNode |
| subclasses, and instead always generating op_debugs whenever we |
| emit a flagged node. |
| |
| -- |
| |
| * CMakeLists.txt: |
| * JavaScriptCore.xcodeproj/project.pbxproj: |
| New DebuggerParseData files. |
| |
| * API/JSScriptRef.cpp: |
| (OpaqueJSScript::OpaqueJSScript): |
| * jsc.cpp: |
| (functionCheckModuleSyntax): |
| * parser/SourceCode.h: |
| (JSC::makeSource): |
| * parser/SourceProvider.cpp: |
| (JSC::SourceProvider::SourceProvider): |
| * parser/SourceProvider.h: |
| (JSC::SourceProvider::sourceType): |
| (JSC::StringSourceProvider::create): |
| (JSC::StringSourceProvider::StringSourceProvider): |
| (JSC::WebAssemblySourceProvider::WebAssemblySourceProvider): |
| (JSC::SourceProvider::startPosition): Deleted. |
| Add a new type on SourceProvider to distinguish if its script was |
| intended to be a Script, Module, or WebAssembly. This information |
| will be needed to know how to best parse this file when the |
| debugger decides to lazily parse. |
| |
| * runtime/Executable.cpp: |
| (JSC::EvalExecutable::EvalExecutable): |
| (JSC::ProgramExecutable::ProgramExecutable): |
| (JSC::ModuleProgramExecutable::ModuleProgramExecutable): |
| (JSC::WebAssemblyExecutable::WebAssemblyExecutable): |
| * runtime/ModuleLoaderPrototype.cpp: |
| (JSC::moduleLoaderPrototypeParseModule): |
| ASSERT the SourceProvider type matches the executable type we are |
| creating for it. |
| |
| * parser/ASTBuilder.h: |
| (JSC::ASTBuilder::breakpointLocation): |
| * parser/SyntaxChecker.h: |
| (JSC::SyntaxChecker::operatorStackPop): |
| When gathering breakpoint positions, get the position from the |
| current node. In the SyntaxChecker, return an invalid position. |
| |
| * parser/Nodes.h: |
| (JSC::ExpressionNode::needsDebugHook): |
| (JSC::ExpressionNode::setNeedsDebugHook): |
| (JSC::StatementNode::needsDebugHook): |
| (JSC::StatementNode::setNeedsDebugHook): |
| When gathering breakpoint positions, mark the node as needing |
| a debug hook. For now we assert op_debugs generated must come |
| from these nodes. Later we should just generate op_debugs for |
| these nodes. |
| |
| * parser/Parser.cpp: |
| (JSC::Parser<LexerType>::Parser): |
| (JSC::Parser<LexerType>::parseStatementListItem): |
| (JSC::Parser<LexerType>::parseDoWhileStatement): |
| (JSC::Parser<LexerType>::parseWhileStatement): |
| (JSC::Parser<LexerType>::parseArrowFunctionSingleExpressionBodySourceElements): |
| (JSC::Parser<LexerType>::parseForStatement): |
| (JSC::Parser<LexerType>::parseWithStatement): |
| (JSC::Parser<LexerType>::parseSwitchStatement): |
| (JSC::Parser<LexerType>::parseStatement): |
| (JSC::Parser<LexerType>::parseFunctionBody): |
| (JSC::Parser<LexerType>::parseFunctionInfo): |
| (JSC::Parser<LexerType>::parseIfStatement): |
| (JSC::Parser<LexerType>::parseAssignmentExpression): |
| * parser/Parser.h: |
| (JSC::parse): |
| Add an optional DebuggerParseData struct to the Parser. When available |
| the Parser will gather debugger data, and parse all functions with the |
| ASTBuilder instead of SyntaxChecking inner functions. |
| |
| * debugger/DebuggerParseData.cpp: Added. |
| (JSC::DebuggerPausePositions::breakpointLocationForLineColumn): |
| (JSC::DebuggerPausePositions::sort): |
| (JSC::gatherDebuggerParseData): |
| (JSC::gatherDebuggerParseDataForSource): |
| * debugger/DebuggerParseData.h: Copied from Source/JavaScriptCore/debugger/DebuggerPrimitives.h. |
| (JSC::DebuggerPausePositions::DebuggerPausePositions): |
| (JSC::DebuggerPausePositions::appendPause): |
| (JSC::DebuggerPausePositions::appendEntry): |
| (JSC::DebuggerPausePositions::appendLeave): |
| The DebuggerParseData struct currently only contains a list of pause positions. |
| Once populated it can resolve an input location to a pause position. |
| |
| * bytecompiler/BytecodeGenerator.cpp: |
| (JSC::BytecodeGenerator::emitCall): |
| (JSC::BytecodeGenerator::emitCallVarargs): |
| (JSC::BytecodeGenerator::emitDebugHook): |
| (JSC::BytecodeGenerator::emitEnumeration): |
| * bytecompiler/BytecodeGenerator.h: |
| * bytecompiler/NodesCodegen.cpp: |
| (JSC::EmptyStatementNode::emitBytecode): |
| (JSC::DebuggerStatementNode::emitBytecode): |
| (JSC::ExprStatementNode::emitBytecode): |
| (JSC::DeclarationStatement::emitBytecode): |
| (JSC::IfElseNode::emitBytecode): |
| (JSC::DoWhileNode::emitBytecode): |
| (JSC::WhileNode::emitBytecode): |
| (JSC::ForNode::emitBytecode): |
| (JSC::ForInNode::emitBytecode): |
| (JSC::ContinueNode::emitBytecode): |
| (JSC::BreakNode::emitBytecode): |
| (JSC::ReturnNode::emitBytecode): |
| (JSC::WithNode::emitBytecode): |
| (JSC::SwitchNode::emitBytecode): |
| (JSC::ThrowNode::emitBytecode): |
| Emit op_debugs for the nodes themselves. Assert when we do that the |
| Parser had marked them as needing a debug hook. |
| |
| * debugger/Breakpoint.h: |
| (JSC::Breakpoint::Breakpoint): |
| A breakpoint may be resolved or unresolved. Debugger::resolveBreakpoint |
| must be used to resolve the breakpoint. Most methods now require a |
| resolved breakpoint. |
| |
| * debugger/Debugger.h: |
| * debugger/Debugger.cpp: |
| (JSC::Debugger::detach): |
| (JSC::Debugger::toggleBreakpoint): |
| (JSC::Debugger::debuggerParseData): |
| (JSC::Debugger::resolveBreakpoint): |
| (JSC::Debugger::setBreakpoint): |
| (JSC::Debugger::clearParsedData): |
| Provide a public method to resolve a breakpoint location in a script. |
| This will gather debugger parse data for the script if none is available. |
| Ensure clients have resolved a breakpoint before attempting to set it. |
| Currently we allow only a single breakpoint at a location. This may |
| need to change if multiple breakpoints resolve to the same location |
| but have different actions. |
| |
| * inspector/ScriptDebugListener.h: |
| ScriptDebugServer::Script is effectively duplicating most of the data from |
| a SourceProvider. We should eliminate this and just use SourceProvider. |
| |
| * inspector/ScriptDebugServer.cpp: |
| (Inspector::ScriptDebugServer::setBreakpointActions): |
| (Inspector::ScriptDebugServer::removeBreakpointActions): |
| (Inspector::ScriptDebugServer::getActionsForBreakpoint): |
| (Inspector::ScriptDebugServer::clearBreakpointActions): |
| (Inspector::ScriptDebugServer::evaluateBreakpointAction): |
| (Inspector::ScriptDebugServer::dispatchDidParseSource): |
| (Inspector::ScriptDebugServer::handleBreakpointHit): |
| (Inspector::ScriptDebugServer::setBreakpoint): Deleted. |
| (Inspector::ScriptDebugServer::removeBreakpoint): Deleted. |
| (Inspector::ScriptDebugServer::clearBreakpoints): Deleted. |
| * inspector/ScriptDebugServer.h: |
| Reduce ScriptDebugServer's involvement in breakpoints to just handling |
| breakpoint actions. Eventually we should eliminate it alltogether and |
| fold breakpoint logic into Debugger or DebugAgent. |
| |
| * inspector/agents/InspectorDebuggerAgent.h: |
| * inspector/agents/InspectorDebuggerAgent.cpp: |
| (Inspector::buildDebuggerLocation): |
| (Inspector::parseLocation): |
| (Inspector::InspectorDebuggerAgent::setBreakpointByUrl): |
| (Inspector::InspectorDebuggerAgent::setBreakpoint): |
| (Inspector::InspectorDebuggerAgent::didSetBreakpoint): |
| (Inspector::InspectorDebuggerAgent::resolveBreakpoint): |
| (Inspector::InspectorDebuggerAgent::removeBreakpoint): |
| (Inspector::InspectorDebuggerAgent::continueToLocation): |
| (Inspector::InspectorDebuggerAgent::didParseSource): |
| (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState): |
| The Inspector can set breakpoints in multiple ways. |
| Ensure that once we have the Script that we always |
| resolve the breakpoint location before setting the |
| breakpoint. The different paths are: |
| |
| - setBreakpoint(scriptId, location) |
| - Here we know the SourceProvider by its SourceID |
| - resolve and set |
| |
| - setBreakpointByURL(url, location) |
| - Search for existing Scripts that match the URL |
| - resolve in each and set |
| - When new Scripts are parsed that match the URL |
| - resolve and set |
| |
| |
| 2016-09-30 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Web Inspector: Stepping out of a function finishes the line that called it. |
| https://bugs.webkit.org/show_bug.cgi?id=155325 |
| <rdar://problem/25094578> |
| |
| Reviewed by Mark Lam. |
| |
| Also addresses: |
| <https://webkit.org/b/161721> Web Inspector: Stepping all the way through program should not cause a pause on the next program that executes |
| <https://webkit.org/b/161716> Web Inspector: Stepping into a function / program should not require stepping to the first statement |
| |
| This change introduces a new op_debug hook: WillExecuteExpression. |
| Currently this new hook is only used for pausing at function calls. |
| We may decide to add it to other places later where pausing with |
| finer granularity then statements (or lines) if useful. |
| |
| This updates the location and behavior of some of the existing debug |
| hooks, to be more consistent and useful if the exact location of the |
| pause is displayed. For example, in control flow statements like |
| `if` and `while`, the pause location is the expression itself that |
| will be evaluated, not the location of the `if` or `while` keyword. |
| For example: |
| |
| if (|condition) |
| while (|condition) |
| |
| Finally, this change gets rid of some unnecessary / useless pause |
| locations such as on entering a function and on entering a program. |
| These pauses are not needed because if there is a statement, we |
| would pause before the statement and it is equivalent. We continue |
| to pause when leaving a function via stepping by uniformly jumping |
| to the closing brace of the function. This gives users a chance |
| to observe state before leaving the function. |
| |
| * bytecode/CodeBlock.cpp: |
| (JSC::debugHookName): |
| * bytecode/UnlinkedCodeBlock.cpp: |
| (JSC::dumpLineColumnEntry): |
| Logging strings for the new debug hook. |
| |
| * bytecompiler/BytecodeGenerator.h: |
| * bytecompiler/BytecodeGenerator.cpp: |
| (JSC::BytecodeGenerator::emitCallInTailPosition): |
| (JSC::BytecodeGenerator::emitCallEval): |
| (JSC::BytecodeGenerator::emitCallVarargsInTailPosition): |
| (JSC::BytecodeGenerator::emitConstructVarargs): |
| (JSC::BytecodeGenerator::emitCallForwardArgumentsInTailPosition): |
| (JSC::BytecodeGenerator::emitCallDefineProperty): |
| (JSC::BytecodeGenerator::emitConstruct): |
| (JSC::BytecodeGenerator::emitGetTemplateObject): |
| (JSC::BytecodeGenerator::emitIteratorNext): |
| (JSC::BytecodeGenerator::emitIteratorNextWithValue): |
| (JSC::BytecodeGenerator::emitIteratorClose): |
| (JSC::BytecodeGenerator::emitDelegateYield): |
| All emitCall variants now take an enum to decide whether or not to |
| emit the WillExecuteExpression debug hook. |
| |
| (JSC::BytecodeGenerator::emitCall): |
| (JSC::BytecodeGenerator::emitCallVarargs): |
| In the two real implementations, actually decide to emit the debug |
| hook or not based on the parameter. |
| |
| (JSC::BytecodeGenerator::emitEnumeration): |
| This is shared looping code used by for..of iteration of iterables. |
| When used by ForOfNode, we want to emit a pause location during |
| iteration. |
| |
| (JSC::BytecodeGenerator::emitWillLeaveCallFrameDebugHook): |
| This is shared call frame leave code to emit a consistent pause |
| location when leaving a function. |
| |
| * bytecompiler/NodesCodegen.cpp: |
| (JSC::EvalFunctionCallNode::emitBytecode): |
| (JSC::FunctionCallValueNode::emitBytecode): |
| (JSC::FunctionCallResolveNode::emitBytecode): |
| (JSC::BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments): |
| (JSC::FunctionCallBracketNode::emitBytecode): |
| (JSC::FunctionCallDotNode::emitBytecode): |
| (JSC::CallFunctionCallDotNode::emitBytecode): |
| (JSC::ApplyFunctionCallDotNode::emitBytecode): |
| (JSC::TaggedTemplateNode::emitBytecode): |
| (JSC::ArrayPatternNode::bindValue): |
| All tail position calls are the function calls that we want to emit |
| debug hooks for. All non-tail call calls appear to be internal |
| implementation details, and these should not have the debug hook. |
| |
| (JSC::IfElseNode::emitBytecode): |
| (JSC::WhileNode::emitBytecode): |
| (JSC::WithNode::emitBytecode): |
| (JSC::SwitchNode::emitBytecode): |
| Make the pause location consistent at the expression. |
| |
| (JSC::DoWhileNode::emitBytecode): |
| Make the pause location consistent at the expression. |
| Remove the errant pause at the do's '}' when entering the do block. |
| |
| (JSC::ForNode::emitBytecode): |
| (JSC::ForInNode::emitMultiLoopBytecode): |
| (JSC::ForOfNode::emitBytecode): |
| Make the pause location consistent at expressions. |
| Also allow stepping to the traditional for loop's |
| update expression, which was previously not possible. |
| |
| (JSC::ReturnNode::emitBytecode): |
| (JSC::FunctionNode::emitBytecode): |
| Make the pause location when leaving a function consistently be the |
| function's closing brace. The two cases are stepping through a return |
| statement, or the implicit return undefined at the end of a function. |
| |
| (JSC::LabelNode::emitBytecode): |
| (JSC::TryNode::emitBytecode): |
| Remove unnecessary pauses that add no value, as they contain a |
| statement and we will then pause at that statement. |
| |
| * parser/Nodes.h: |
| (JSC::StatementNode::isFunctionNode): |
| (JSC::StatementNode::isForOfNode): |
| (JSC::EnumerationNode::lexpr): |
| (JSC::ForOfNode::isForOfNode): |
| New virtual methods to distinguish different nodes. |
| |
| * debugger/Debugger.h: |
| Rename m_pauseAtNextStatement to m_pauseAtNextOpportunity. |
| This is the finest granularity of stepping, and it can be |
| pausing at a location that is not a statement. |
| Introduce state to properly handle step out and stepping |
| when there are multiple expressions in a statement. |
| |
| * debugger/Debugger.cpp: |
| (JSC::Debugger::Debugger): |
| (JSC::Debugger::setPauseOnNextStatement): |
| (JSC::Debugger::breakProgram): |
| (JSC::Debugger::continueProgram): |
| (JSC::Debugger::stepIntoStatement): |
| (JSC::Debugger::exception): |
| (JSC::Debugger::didReachBreakpoint): |
| |
| Use new variable names, and clarify if we should attempt |
| to pause or not. |
| |
| (JSC::Debugger::stepOutOfFunction): |
| Set a new state to indicate a step out action. |
| |
| (JSC::Debugger::updateCallFrame): |
| (JSC::Debugger::updateCallFrameAndPauseIfNeeded): Deleted. |
| (JSC::Debugger::updateCallFrameInternal): |
| (JSC::Debugger::pauseIfNeeded): |
| Allow updateCallFrame to either attempt a pause or not. |
| |
| (JSC::Debugger::atStatement): |
| Attempt pause and reset the at first expression flag. |
| |
| (JSC::Debugger::atExpression): |
| Attempt a pause when not stepping over. Also skip |
| the first expression pause, since that would be |
| equivalent to when we paused for the expression. |
| |
| (JSC::Debugger::callEvent): |
| Do not pause when entering a function. |
| |
| (JSC::Debugger::returnEvent): |
| Attempt pause when leaving a function. |
| If the user did a step-over and is leaving the |
| function, then behave like step-out. |
| |
| (JSC::Debugger::unwindEvent): |
| Behave like return except don't change any |
| pausing states. If we needed to pause the |
| Debugger::exception will have handled it. |
| |
| (JSC::Debugger::willExecuteProgram): |
| Do not pause when entering a program. |
| |
| (JSC::Debugger::didExecuteProgram): |
| Attempt pause when leaving a program that has a caller. |
| This can be useful for exiting an eval(...) program. |
| Otherwise treat this like return, and step-over out |
| of the program should behave like step-out. We use |
| pause at next opportunity because there may be extra |
| callframes we do not know about. |
| When the program doesn't have a parent, clear all |
| our state so we don't errantly pause on the next |
| JavaScript microtask that gets executed. |
| |
| (JSC::Debugger::clearNextPauseState): |
| Helper to clear all of the pause states now that |
| it happens in a couple places. |
| |
| * interpreter/Interpreter.cpp: |
| (JSC::notifyDebuggerOfUnwinding): |
| Treat unwinding slightly differently from returning. |
| We will not want to pause when unwinding callframes. |
| |
| (JSC::Interpreter::debug): |
| * interpreter/Interpreter.h: |
| New debug hook. |
| |
| * inspector/agents/InspectorDebuggerAgent.cpp: |
| (Inspector::InspectorDebuggerAgent::stepInto): |
| (Inspector::InspectorDebuggerAgent::didPause): |
| * inspector/agents/InspectorDebuggerAgent.h: |
| Remove unnecessary stepInto code notification for listeners. |
| The listeners are never notified if the debugger resumes, |
| so whatever state they were setting by this is going to |
| get out of date. |
| |
| 2016-09-30 Saam Barati <sbarati@apple.com> |
| |
| Arrow functions should not allow duplicate parameter names |
| https://bugs.webkit.org/show_bug.cgi?id=162741 |
| |
| Reviewed by Filip Pizlo. |
| |
| This patch makes parsing arrow function parameters throw |
| a syntax error when there are duplicate parameter names. |
| It also starts to make some syntax errors for arrow functions |
| better, however, this is trickier than it seems since we need |
| to choose between two parsing productions when we decide to |
| throw a syntax error. I'm going to work on this problem |
| in another patch specifically devoted to making the error |
| messages better for parsing arrow functions: |
| https://bugs.webkit.org/show_bug.cgi?id=162794 |
| |
| * parser/Parser.cpp: |
| (JSC::Parser<LexerType>::isArrowFunctionParameters): |
| (JSC::Parser<LexerType>::parseFormalParameters): |
| (JSC::Parser<LexerType>::parseFunctionParameters): |
| (JSC::Parser<LexerType>::parseAssignmentExpression): |
| * parser/Parser.h: |
| |
| 2016-09-30 Mark Lam <mark.lam@apple.com> |
| |
| Use topVMEntryFrame to determine whether to skip the re-throw of a simulated throw. |
| https://bugs.webkit.org/show_bug.cgi?id=162793 |
| |
| Reviewed by Saam Barati. |
| |
| Change the ThrowScope destructor to use topVMEntryFrame (instead of topCallFrame) |
| in the determination of whether to skip the re-throw of a simulated throw. This |
| is needed because the topCallFrame is not updated in operationConstructArityCheck() |
| (and does not need to be), whereas topVMEntryFrame is always updated properly. |
| Hence, we should just switch to using the more reliable topVMEntryFrame instead. |
| |
| This issue was discovered by existing JSC tests when exception check validation |
| is enabled. |
| |
| * runtime/ThrowScope.cpp: |
| (JSC::ThrowScope::~ThrowScope): |
| |
| 2016-09-30 Filip Pizlo <fpizlo@apple.com> |
| |
| 64-bit LLInt needs to have a concurrency-aware barrier |
| https://bugs.webkit.org/show_bug.cgi?id=162790 |
| |
| Reviewed by Mark Lam. |
| |
| In a concurrent GC the barrier definitely has to be after the store, not before it. |
| |
| * llint/LowLevelInterpreter64.asm: |
| |
| 2016-09-29 Filip Pizlo <fpizlo@apple.com> |
| |
| Air should have a way of expressing additional instruction flags |
| https://bugs.webkit.org/show_bug.cgi?id=162699 |
| |
| Reviewed by Mark Lam. |
| |
| This follows a similar change in B3 (r206595) and replaces Air::Opcode with Air::Kind, |
| which holds onto the opcode and some additional flags. Because Air is an orthogonal ISA |
| (the opcode tells you what the operation does but each operand is allowed to also contain |
| effectively instructions for what to do to read or write that operand), the flags are |
| meant to be orthogonal to opcode. This allows us to say things like Add32<Trap>, which |
| makes sense if any of the operands to the Add32 are addresses. |
| |
| To demonstrate the flags facility this partly adds a trap flag to Air. B3 doesn't use it |
| yet, but I made sure that Air respects it. Basically that means blocking DCE when the flag |
| is set, by making it imply hasNonArgNonControlEffects. |
| |
| * CMakeLists.txt: |
| * JavaScriptCore.xcodeproj/project.pbxproj: |
| * b3/B3CheckSpecial.cpp: |
| (JSC::B3::Air::numB3Args): |
| (JSC::B3::CheckSpecial::Key::Key): |
| (JSC::B3::CheckSpecial::Key::dump): |
| (JSC::B3::CheckSpecial::CheckSpecial): |
| (JSC::B3::CheckSpecial::hiddenBranch): |
| (JSC::B3::CheckSpecial::forEachArg): |
| (JSC::B3::CheckSpecial::generate): |
| (JSC::B3::CheckSpecial::dumpImpl): |
| (JSC::B3::CheckSpecial::deepDumpImpl): |
| * b3/B3CheckSpecial.h: |
| (JSC::B3::CheckSpecial::Key::Key): |
| (JSC::B3::CheckSpecial::Key::operator==): |
| (JSC::B3::CheckSpecial::Key::kind): |
| (JSC::B3::CheckSpecial::Key::hash): |
| (JSC::B3::CheckSpecial::Key::opcode): Deleted. |
| * b3/B3Kind.cpp: |
| (JSC::B3::Kind::dump): |
| * b3/air/AirDumpAsJS.cpp: |
| (JSC::B3::Air::dumpAsJS): |
| * b3/air/AirFixObviousSpills.cpp: |
| * b3/air/AirFixPartialRegisterStalls.cpp: |
| * b3/air/AirGenerate.cpp: |
| (JSC::B3::Air::generate): |
| * b3/air/AirHandleCalleeSaves.cpp: |
| (JSC::B3::Air::handleCalleeSaves): |
| * b3/air/AirInst.cpp: |
| (JSC::B3::Air::Inst::jsHash): |
| (JSC::B3::Air::Inst::dump): |
| * b3/air/AirInst.h: |
| (JSC::B3::Air::Inst::Inst): |
| (JSC::B3::Air::Inst::kind): |
| (JSC::B3::Air::Inst::operator bool): |
| (JSC::B3::Air::Inst::opcode): Deleted. |
| * b3/air/AirInstInlines.h: |
| (JSC::B3::Air::Inst::extraClobberedRegs): |
| (JSC::B3::Air::Inst::extraEarlyClobberedRegs): |
| (JSC::B3::Air::Inst::forEachDefWithExtraClobberedRegs): |
| (JSC::B3::Air::Inst::reportUsedRegisters): |
| (JSC::B3::Air::Inst::shouldTryAliasingDef): |
| * b3/air/AirIteratedRegisterCoalescing.cpp: |
| * b3/air/AirKind.cpp: Added. |
| (JSC::B3::Air::Kind::dump): |
| * b3/air/AirKind.h: Added. |
| (JSC::B3::Air::Kind::Kind): |
| (JSC::B3::Air::Kind::operator==): |
| (JSC::B3::Air::Kind::operator!=): |
| (JSC::B3::Air::Kind::hash): |
| (JSC::B3::Air::Kind::operator bool): |
| * b3/air/AirLowerAfterRegAlloc.cpp: |
| (JSC::B3::Air::lowerAfterRegAlloc): |
| * b3/air/AirLowerEntrySwitch.cpp: |
| (JSC::B3::Air::lowerEntrySwitch): |
| * b3/air/AirLowerMacros.cpp: |
| (JSC::B3::Air::lowerMacros): |
| * b3/air/AirOptimizeBlockOrder.cpp: |
| (JSC::B3::Air::optimizeBlockOrder): |
| * b3/air/AirReportUsedRegisters.cpp: |
| (JSC::B3::Air::reportUsedRegisters): |
| * b3/air/AirSimplifyCFG.cpp: |
| (JSC::B3::Air::simplifyCFG): |
| * b3/air/AirTmpWidth.cpp: |
| (JSC::B3::Air::TmpWidth::recompute): |
| * b3/air/AirUseCounts.h: |
| (JSC::B3::Air::UseCounts::UseCounts): |
| * b3/air/AirValidate.cpp: |
| * b3/air/opcode_generator.rb: |
| * b3/testb3.cpp: |
| (JSC::B3::testTernarySubInstructionSelection): |
| (JSC::B3::testBranchBitAndImmFusion): |
| |
| 2016-09-29 Filip Pizlo <fpizlo@apple.com> |
| |
| REGRESSION(r206555): It made Dromaeo/jslib-style-jquery.html crash |
| https://bugs.webkit.org/show_bug.cgi?id=162721 |
| |
| Reviewed by Keith Miller. |
| |
| The put_by_id-in-put_by_val optimization had the write barrier in the wrong place and |
| incorrectly filtered on value instead of base. |
| |
| No reduced test case. You really need to run Dromaeo/jslib to catch it. I love Dromaeo's |
| ability to catch GC bugs. |
| |
| * jit/JITPropertyAccess.cpp: |
| (JSC::JIT::emitPutByValWithCachedId): |
| |
| 2016-09-29 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Arrow functions do not infer name from computed property but normal functions do |
| https://bugs.webkit.org/show_bug.cgi?id=162720 |
| |
| Reviewed by Saam Barati. |
| |
| * bytecompiler/BytecodeGenerator.cpp: |
| (JSC::BytecodeGenerator::emitSetFunctionNameIfNeeded): |
| Set function name on arrow functions as well. |
| |
| 2016-09-29 Joseph Pecoraro <pecoraro@apple.com> |
| |
| test262: class and function names should be inferred in assignment |
| https://bugs.webkit.org/show_bug.cgi?id=146262 |
| |
| Reviewed by Saam Barati. |
| |
| * parser/ASTBuilder.h: |
| (JSC::ASTBuilder::appendParameter): |
| (JSC::ASTBuilder::appendArrayPatternEntry): |
| (JSC::ASTBuilder::appendObjectPatternEntry): |
| (JSC::ASTBuilder::tryInferFunctionNameInPattern): |
| Assign names to default value functions and classes in destructuring. |
| |
| (JSC::ASTBuilder::createAssignResolve): |
| (JSC::ASTBuilder::createProperty): |
| (JSC::ASTBuilder::makeAssignNode): |
| Assign names to both normal and arrow functions. |
| |
| * parser/Nodes.h: |
| (JSC::ExpressionNode::isBaseFuncExprNode): |
| Both functions and arrow functions infer name, they both extend |
| this base so give the base an is check. |
| |
| 2016-09-28 Filip Pizlo <fpizlo@apple.com> |
| |
| B3 opcodes should leave room for flags |
| https://bugs.webkit.org/show_bug.cgi?id=162692 |
| |
| Reviewed by Keith Miller. |
| |
| It used to be that the main thing that determined what a Value did was the opcode. The |
| Opcode was how you knew what subclass of Value you had. The opcode told you what the Value |
| actually did. This change replaces Opcode with Kind, which is a tuple of opcode and other |
| stuff. |
| |
| Opcodes are great, and that's how most compilers work. But opcodes are one-dimensional. Here |
| is how this manifests. Say you have an opcode, like Load. You will be happy if your IR has |
| one Load opcode. But then, you might add Load8S/Load8Z/Load16S/Load16Z opcodes, as we have |
| done in B3. B3 has one dimension of Load opcodes, which determines something like the C type |
| of the load. But in the very near future, we will want to add two more dimensions to Loads: |
| |
| - A flag to say if the load traps. |
| - A flag to say if the load has acquire semantics. |
| |
| Mapping these three dimensions (type, trap, acquire) onto the one-dimensional Opcode space |
| would create mayham: Load8S, Load8STrap, Load8SAcquire, Load8STrapAcquire, Load8Z, |
| Load8ZTrap, etc. |
| |
| This happens in other parts of the IR. For example, we have a dimension of arithmetic |
| operations: add, sub, mul, div, mod, etc. Then we have the chill flag. But since opcodes |
| are one-dimensional, that means having ChillDiv and ChillMod, and tons of places in the |
| compiler that case on both Div and ChillDiv, or case on both Mod and ChillMod, since they |
| are only interested in the kind of arithmetic being done and not the chillness. |
| |
| Though the examples all involve bits (chill or not, trapping or not, etc), I can imagine |
| other properties that behave more like small enums, like if we fill out more memory ordering |
| modes other than just "acquire? yes/no". There will eventually have to be something like a |
| std::memory_order associated with memory accesses. |
| |
| One approach to this problem is to have a Value subclass that contains fields with the meta |
| data. I don't like this for two reasons: |
| |
| - In bug 162688, I want to make trapping memory accesses have stackmaps. This means that a |
| trapping memory access would have a different Value subclass than a non-trapping memory |
| access. So, this meta-data needs to channel into ValueType::accepts(). Currently that |
| takes Opcode and nothing else. |
| |
| - Compiler IRs are all about making common tasks easy. If it becomes commonplace for opcodes |
| to require a custom Value subclass just for a bit then that's not very easy. |
| |
| This change addresses this problem by making the compiler pass around Kinds rather than |
| Opcodes. A Kind contains an Opcode as well as any number of opcode-specific bits. This |
| change demonstrates how Kind should be used by converting chillness to it. Kind has |
| hasIsChill(), isChill(), and setIsChill() methods. hasIsChill() is true only for Div and |
| Mod. setIsChill() asserts if !hasIsChill(). If you want to create a Chill Div, you say |
| chill(Div). IR dumps will print it like this: |
| |
| Int32 @38 = Div<Chill>(@36, @37, DFG:@24, ControlDependent) |
| |
| Where "Div<Chill>" is how a Kind that hasExtraBits() dumps itself. If a Kind does not |
| hasExtraBits() (the normal case) then it dumps like a normal Opcode (without the "<>"). |
| |
| I replaced many uses of Opcode with Kind. New code has to be mindful that Opcode may not be |
| the right way to summarize what a value does, and so in many cases it's better to carry |
| around a Kind instead - especially if you will use it to stamp out new Values. Opcode is no |
| longer sufficient to perform a dynamic Value cast, since that code now uses Kind. ValueKey |
| now wants a Kind instead of an Opcode. All Value constructors now take Kind instead of |
| Opcode. But most opcodes don't get any extra Kind bits, and so the code that operates on |
| those opcodes is largely unchanged. |
| |
| * CMakeLists.txt: |
| * JavaScriptCore.xcodeproj/project.pbxproj: |
| * b3/B3ArgumentRegValue.h: |
| * b3/B3CCallValue.h: |
| * b3/B3CheckValue.cpp: |
| (JSC::B3::CheckValue::convertToAdd): |
| (JSC::B3::CheckValue::CheckValue): |
| * b3/B3CheckValue.h: |
| (JSC::B3::CheckValue::accepts): |
| * b3/B3Const32Value.h: |
| * b3/B3Const64Value.h: |
| * b3/B3ConstDoubleValue.h: |
| * b3/B3ConstFloatValue.h: |
| * b3/B3FenceValue.h: |
| * b3/B3Kind.cpp: Added. |
| (JSC::B3::Kind::dump): |
| * b3/B3Kind.h: Added. |
| (JSC::B3::Kind::Kind): |
| (JSC::B3::Kind::opcode): |
| (JSC::B3::Kind::setOpcode): |
| (JSC::B3::Kind::hasExtraBits): |
| (JSC::B3::Kind::hasIsChill): |
| (JSC::B3::Kind::isChill): |
| (JSC::B3::Kind::setIsChill): |
| (JSC::B3::Kind::operator==): |
| (JSC::B3::Kind::operator!=): |
| (JSC::B3::Kind::hash): |
| (JSC::B3::Kind::isHashTableDeletedValue): |
| (JSC::B3::chill): |
| (JSC::B3::KindHash::hash): |
| (JSC::B3::KindHash::equal): |
| * b3/B3LowerMacros.cpp: |
| * b3/B3LowerToAir.cpp: |
| (JSC::B3::Air::LowerToAir::lower): |
| * b3/B3MemoryValue.h: |
| * b3/B3Opcode.cpp: |
| (WTF::printInternal): |
| * b3/B3Opcode.h: |
| * b3/B3PatchpointValue.h: |
| (JSC::B3::PatchpointValue::accepts): |
| * b3/B3ReduceStrength.cpp: |
| * b3/B3SlotBaseValue.h: |
| * b3/B3StackmapValue.cpp: |
| (JSC::B3::StackmapValue::StackmapValue): |
| * b3/B3StackmapValue.h: |
| * b3/B3SwitchValue.h: |
| (JSC::B3::SwitchValue::accepts): |
| * b3/B3UpsilonValue.h: |
| * b3/B3Validate.cpp: |
| * b3/B3Value.cpp: |
| (JSC::B3::Value::dump): |
| (JSC::B3::Value::deepDump): |
| (JSC::B3::Value::invertedCompare): |
| (JSC::B3::Value::effects): |
| (JSC::B3::Value::key): |
| (JSC::B3::Value::typeFor): |
| (JSC::B3::Value::badKind): |
| (JSC::B3::Value::badOpcode): Deleted. |
| * b3/B3Value.h: |
| * b3/B3ValueInlines.h: |
| (JSC::B3::Value::as): |
| * b3/B3ValueKey.cpp: |
| (JSC::B3::ValueKey::dump): |
| (JSC::B3::ValueKey::materialize): |
| * b3/B3ValueKey.h: |
| (JSC::B3::ValueKey::ValueKey): |
| (JSC::B3::ValueKey::kind): |
| (JSC::B3::ValueKey::opcode): |
| (JSC::B3::ValueKey::operator==): |
| (JSC::B3::ValueKey::hash): |
| * b3/B3ValueKeyInlines.h: |
| (JSC::B3::ValueKey::ValueKey): |
| * b3/B3VariableValue.cpp: |
| (JSC::B3::VariableValue::VariableValue): |
| * b3/B3VariableValue.h: |
| * b3/testb3.cpp: |
| (JSC::B3::testChillDiv): |
| (JSC::B3::testChillDivTwice): |
| (JSC::B3::testChillDiv64): |
| (JSC::B3::testChillModArg): |
| (JSC::B3::testChillModArgs): |
| (JSC::B3::testChillModImms): |
| (JSC::B3::testChillModArg32): |
| (JSC::B3::testChillModArgs32): |
| (JSC::B3::testChillModImms32): |
| (JSC::B3::testSwitchChillDiv): |
| (JSC::B3::testEntrySwitchWithCommonPaths): |
| (JSC::B3::testEntrySwitchWithCommonPathsAndNonTrivialEntrypoint): |
| * ftl/FTLOutput.cpp: |
| (JSC::FTL::Output::chillDiv): |
| (JSC::FTL::Output::chillMod): |
| |
| 2016-09-29 Saam Barati <sbarati@apple.com> |
| |
| We don't properly propagate non-simple-parameter-list when parsing a setter |
| https://bugs.webkit.org/show_bug.cgi?id=160483 |
| |
| Reviewed by Joseph Pecoraro. |
| |
| * parser/Parser.cpp: |
| (JSC::Parser<LexerType>::parseFunctionParameters): |
| |
| 2016-09-28 Saam Barati <sbarati@apple.com> |
| |
| stringProtoFuncRepeatCharacter will return `null` when it should not |
| https://bugs.webkit.org/show_bug.cgi?id=161944 |
| |
| Reviewed by Yusuke Suzuki. |
| |
| stringProtoFuncRepeatCharacter was expecting its second argument |
| to always be a boxed integer. This is not correct. The DFG may decide |
| to represent a particular value as a double instead of integer. This |
| function needs to have correct behavior when its second argument is |
| a boxed double. I also added an assertion stating that the second argument |
| is always a number. We can guarantee this since it's only called from |
| builtins. |
| |
| * runtime/StringPrototype.cpp: |
| (JSC::stringProtoFuncRepeatCharacter): |
| |
| 2016-09-28 Filip Pizlo <fpizlo@apple.com> |
| |
| The write barrier should be down with TSO |
| https://bugs.webkit.org/show_bug.cgi?id=162316 |
| |
| Reviewed by Geoffrey Garen. |
| |
| This makes our write barrier behave correctly when it races with the collector. The |
| collector wants to do this when visiting: |
| |
| object->cellState = black |
| visit(object) |
| |
| The mutator wants to do this when storing: |
| |
| object->property = newValue |
| if (object->cellState == black) |
| remember(object) |
| |
| Prior to this change, this didn't work right because the compiler would sometimes place |
| barriers before the store to the property and because the mutator did not have adequate |
| fences. |
| |
| Prior to this change, the DFG and FTL would emit this: |
| |
| if (object->cellState == black) |
| remember(object) |
| object->property = newValue |
| |
| Which is wrong, because the object could start being scanned just after the cellState |
| check, at which point the store would be lost. We need to confirm that the state was not |
| black *after* the store! This change was harder than you'd expect: placing the barrier |
| after the store broke B3's ability to do its super crazy ninja CSE on some store-load |
| redundancies. Because the B3 CSE has some moves that the DFG CSE lacks, the DFG CSE's |
| ability to ignore barriers didn't help. I fixed this by having the FTL convey precise |
| heap ranges for the patchpoint corresponding to the barrier slow path. It reads the world |
| (because of the store-load fence) and it writes only cellState (because the B3 heap ranges |
| don't have any way to represent any of the GC's other state, which means that B3 does not |
| have to worry about aliasing with any of that). |
| |
| The collector already uses a store-load fence on x86 just after setting the cellState and |
| before visiting the object. The mutator needs to do the same. But we cannot put a |
| store-load fence of any kind before store barriers, because that causes enormous slow |
| downs. In the worst case, Octane/richards slowed down by 90%! That's crazy! However, the |
| overall slow downs were small enough (0-15% on benchmark suite aggregates) that it would be |
| reasonable if the slow down only happened while the GC was running. Then, the concurrent GC |
| would lift throughput-while-collecting from 0% of peak to 85% of peak. This changes the |
| barrier so that it looks like this: |
| |
| if (object->cellState <= heap.sneakyBlackThreshold) |
| slowPath(object) |
| |
| Where sneakyBlackThreshold is the normal blackThreshold when we're not collecting, or a |
| tautoligical threshold (that makes everything look black) when we are collecting. This |
| turns out to not be any more expensive than the barrier in tip of tree when the GC is not |
| running, or a 0-15% slow-down when it is "running". (Of course we don't run the GC |
| concurrently yet. I still have more work to do.) The slowPath() does some extra work to |
| check if we are concurrently collecting; if so, it does a fence and rechecks if the object |
| really did need that barrier. |
| |
| This also reintroduces elimination of redundant store barriers, which was lost in the last |
| store barrier change. We can only do it when there is no possibility of GC, exit, or |
| exceptions between the two store barriers. We could remove the exit/exception limitation if |
| we taught OSR exit how to buffer store barriers, which is an insane thing to do considering |
| that I've never been able to detect a win from redundant store barrier elimination. I just |
| want us to have it for stupidly obvious situations, like a tight sequence of stores to the |
| same object. This same optimization also sometimes strength-reduces the store barrier so |
| that it uses a constant black threshold rather than the sneaky one, thereby saving one |
| load. |
| |
| Even with all of those optimizations, I still had problems with barrier cost. I found that one |
| of the benchmarks that was being hit particularly hard was JetStream/regexp-2010. Fortunately |
| that benchmark does most of its barriers in a tight C++ loop in RegExpMatchesArray.h. When we |
| know what we're doing, we can defer GC around a bunch of object initializations and then remove |
| all of the barriers between any of the objects allocated within the deferral. Unfortunately, |
| our GC deferral mechanism isn't really performant enough to make this be a worthwhile |
| optimization. The most efficient version of such an optimization that I could come up with was |
| to have a DeferralContext object that houses a boolean that is false by default, but the GC |
| writes true into it if it would have wanted to GC. You thread a pointer to the deferralContext |
| through all of your allocations. This kind of mechanism has the overhead of a zero |
| initialization on the stack on entry and a zero check on exit. This is probably even efficient |
| enough that we could start thinking about having the DFG use it, for example if we found a |
| bounded-time section of code with a lot of barriers and entry/exit sites that aren't totally |
| wacky. This optimization took this patch from 0.68% JetStream regressed to neutral, according |
| to my latest data. |
| |
| Finally, an earlier version of this change put the store-load fence in B3 IR, so I ended up |
| adding FTLOutput support for it and AbstractHeapRepository magic for decorating the heaps. |
| I think we might as well keep that, it'll be useful. |
| |
| * CMakeLists.txt: |
| * JavaScriptCore.xcodeproj/project.pbxproj: |
| * assembler/MacroAssembler.h: |
| (JSC::MacroAssembler::branch32): |
| * assembler/MacroAssemblerX86_64.h: |
| (JSC::MacroAssemblerX86_64::branch32): |
| (JSC::MacroAssemblerX86_64::branch64): Deleted. |
| * bytecode/PolymorphicAccess.cpp: |
| (JSC::AccessCase::generateImpl): |
| * dfg/DFGAbstractHeap.h: |
| * dfg/DFGAbstractInterpreterInlines.h: |
| (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): |
| * dfg/DFGClobberize.h: |
| (JSC::DFG::clobberize): |
| * dfg/DFGClobbersExitState.cpp: |
| (JSC::DFG::clobbersExitState): |
| * dfg/DFGDoesGC.cpp: |
| (JSC::DFG::doesGC): |
| * dfg/DFGFixupPhase.cpp: |
| (JSC::DFG::FixupPhase::fixupNode): |
| * dfg/DFGMayExit.cpp: |
| * dfg/DFGNode.h: |
| (JSC::DFG::Node::isStoreBarrier): |
| * dfg/DFGNodeType.h: |
| * dfg/DFGPlan.cpp: |
| (JSC::DFG::Plan::compileInThreadImpl): |
| * dfg/DFGPredictionPropagationPhase.cpp: |
| * dfg/DFGSafeToExecute.h: |
| (JSC::DFG::safeToExecute): |
| * dfg/DFGSpeculativeJIT.cpp: |
| (JSC::DFG::SpeculativeJIT::compileStoreBarrier): |
| (JSC::DFG::SpeculativeJIT::storeToWriteBarrierBuffer): Deleted. |
| (JSC::DFG::SpeculativeJIT::writeBarrier): Deleted. |
| * dfg/DFGSpeculativeJIT.h: |
| * dfg/DFGSpeculativeJIT32_64.cpp: |
| (JSC::DFG::SpeculativeJIT::compile): |
| (JSC::DFG::SpeculativeJIT::compileBaseValueStoreBarrier): Deleted. |
| (JSC::DFG::SpeculativeJIT::writeBarrier): Deleted. |
| * dfg/DFGSpeculativeJIT64.cpp: |
| (JSC::DFG::SpeculativeJIT::compile): |
| (JSC::DFG::SpeculativeJIT::compileBaseValueStoreBarrier): Deleted. |
| (JSC::DFG::SpeculativeJIT::writeBarrier): Deleted. |
| * dfg/DFGStoreBarrierClusteringPhase.cpp: Added. |
| (JSC::DFG::performStoreBarrierClustering): |
| * dfg/DFGStoreBarrierClusteringPhase.h: Added. |
| * dfg/DFGStoreBarrierInsertionPhase.cpp: |
| * dfg/DFGStoreBarrierInsertionPhase.h: |
| * ftl/FTLAbstractHeap.h: |
| (JSC::FTL::AbsoluteAbstractHeap::at): |
| (JSC::FTL::AbsoluteAbstractHeap::operator[]): |
| * ftl/FTLAbstractHeapRepository.cpp: |
| (JSC::FTL::AbstractHeapRepository::decorateFenceRead): |
| (JSC::FTL::AbstractHeapRepository::decorateFenceWrite): |
| (JSC::FTL::AbstractHeapRepository::computeRangesAndDecorateInstructions): |
| * ftl/FTLAbstractHeapRepository.h: |
| * ftl/FTLCapabilities.cpp: |
| (JSC::FTL::canCompile): |
| * ftl/FTLLowerDFGToB3.cpp: |
| (JSC::FTL::DFG::LowerDFGToB3::compileNode): |
| (JSC::FTL::DFG::LowerDFGToB3::compileStoreBarrier): |
| (JSC::FTL::DFG::LowerDFGToB3::storageForTransition): |
| (JSC::FTL::DFG::LowerDFGToB3::lazySlowPath): |
| (JSC::FTL::DFG::LowerDFGToB3::emitStoreBarrier): |
| * ftl/FTLOutput.cpp: |
| (JSC::FTL::Output::fence): |
| (JSC::FTL::Output::absolute): |
| * ftl/FTLOutput.h: |
| * heap/CellState.h: |
| (JSC::isWithinThreshold): |
| (JSC::isBlack): |
| * heap/Heap.cpp: |
| (JSC::Heap::writeBarrierSlowPath): |
| * heap/Heap.h: |
| (JSC::Heap::barrierShouldBeFenced): |
| (JSC::Heap::addressOfBarrierShouldBeFenced): |
| (JSC::Heap::sneakyBlackThreshold): |
| (JSC::Heap::addressOfSneakyBlackThreshold): |
| * heap/HeapInlines.h: |
| (JSC::Heap::writeBarrier): |
| (JSC::Heap::writeBarrierWithoutFence): |
| * jit/AssemblyHelpers.h: |
| (JSC::AssemblyHelpers::jumpIfIsRememberedOrInEdenWithoutFence): |
| (JSC::AssemblyHelpers::sneakyJumpIfIsRememberedOrInEden): |
| (JSC::AssemblyHelpers::jumpIfIsRememberedOrInEden): |
| (JSC::AssemblyHelpers::storeBarrierStoreLoadFence): |
| (JSC::AssemblyHelpers::jumpIfStoreBarrierStoreLoadFenceNotNeeded): |
| * jit/JITOperations.cpp: |
| * jit/JITOperations.h: |
| * jit/JITPropertyAccess.cpp: |
| (JSC::JIT::emit_op_put_by_id): |
| (JSC::JIT::emitWriteBarrier): |
| (JSC::JIT::privateCompilePutByVal): |
| * jit/JITPropertyAccess32_64.cpp: |
| (JSC::JIT::emit_op_put_by_id): |
| * llint/LowLevelInterpreter.asm: |
| * offlineasm/x86.rb: |
| * runtime/Options.h: |
| |
| 2016-09-27 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Improve useCodeCache Option description string. |
| |
| * runtime/Options.h: |
| Address late review comments and clarify description. |
| |
| 2016-09-28 Filip Pizlo <fpizlo@apple.com> |
| |
| Optimize B3->Air lowering of Fence on ARM |
| https://bugs.webkit.org/show_bug.cgi?id=162342 |
| |
| Reviewed by Geoffrey Garen. |
| |
| This gives us comprehensive support for standalone fences on x86 and ARM. The changes are as |
| follows: |
| |
| - Sets in stone the rule that the heaps of a B3::Fence tell you what the fence protects. If the |
| fence reads, it protects motion of stores. If the fence writes, it protects motion of loads. |
| This allows us to express for example load-load fences in a portable way: on x86 they will just |
| block B3 optimizations and emit no code, while on ARM you will get some fence. |
| |
| - Adds comprehensive support for WTF-style fences in the ARM assembler. I simplified it just a bit |
| to match what B3, the main client, knows. There are three fences: MemoryFence, StoreFence, and |
| LoadFence. On x86, MemoryFence is ortop while StoreFence and LoadFence emit no code. On ARM64, |
| MemoryFence and LoadFence are dmb ish while StoreFence is dmb ishst. |
| |
| - Tests! To test this, I needed to teach the disassembler how to disassemble dmb ish and dmb |
| ishst. I think that the canonical way to do it would be to create a group for dmb and then teach |
| that group how to decode the operands. But I don't actually know what are all of the ways of |
| encoding dmb, so I'd rather that unrecognized encodings fall through to the ".long blah" |
| bailout. So, this creates explicit matching rules for "dmb ish" and "dmb ishst", which is the |
| most conservative thing we can do. |
| |
| * assembler/ARM64Assembler.h: |
| (JSC::ARM64Assembler::dmbISH): |
| (JSC::ARM64Assembler::dmbISHST): |
| (JSC::ARM64Assembler::dmbSY): Deleted. |
| * assembler/MacroAssemblerARM64.h: |
| (JSC::MacroAssemblerARM64::memoryFence): |
| (JSC::MacroAssemblerARM64::storeFence): |
| (JSC::MacroAssemblerARM64::loadFence): |
| * assembler/MacroAssemblerX86Common.h: |
| (JSC::MacroAssemblerX86Common::storeFence): |
| (JSC::MacroAssemblerX86Common::loadFence): |
| * b3/B3FenceValue.h: |
| * b3/B3LowerToAir.cpp: |
| (JSC::B3::Air::LowerToAir::lower): |
| * b3/air/AirOpcode.opcodes: |
| * b3/testb3.cpp: |
| (JSC::B3::testMemoryFence): |
| (JSC::B3::testStoreFence): |
| (JSC::B3::testLoadFence): |
| (JSC::B3::run): |
| (JSC::B3::testX86MFence): Deleted. |
| (JSC::B3::testX86CompilerFence): Deleted. |
| * disassembler/ARM64/A64DOpcode.cpp: |
| (JSC::ARM64Disassembler::A64DOpcodeDmbIsh::format): |
| (JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::format): |
| * disassembler/ARM64/A64DOpcode.h: |
| (JSC::ARM64Disassembler::A64DOpcodeDmbIsh::opName): |
| (JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::opName): |
| |
| 2016-09-28 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Adopt #pragma once in some generated resources |
| https://bugs.webkit.org/show_bug.cgi?id=162666 |
| |
| Reviewed by Alex Christensen. |
| |
| * Scripts/builtins/builtins_generate_combined_header.py: |
| * Scripts/builtins/builtins_generate_internals_wrapper_header.py: |
| * Scripts/builtins/builtins_generate_internals_wrapper_implementation.py: |
| * Scripts/builtins/builtins_generate_separate_header.py: |
| * Scripts/builtins/builtins_generate_wrapper_header.py: |
| * Scripts/builtins/builtins_generate_wrapper_implementation.py: |
| Remove headerGuard attribute unused by templates. |
| |
| * Scripts/tests/builtins/expected/JavaScriptCore-Operations.Promise-Combined.js-result: Removed. |
| No such test exists. It was likely renamed. |
| |
| * generate-bytecode-files: |
| Simplify header guard output. |
| |
| * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: |
| (ObjCBackendDispatcherHeaderGenerator.generate_output): |
| * replay/scripts/CodeGeneratorReplayInputs.py: |
| (Generator.generate_header): |
| * replay/scripts/CodeGeneratorReplayInputsTemplates.py: |
| Simplify header guard output. |
| |
| * replay/scripts/tests/expected/generate-enum-encoding-helpers-with-guarded-values.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-enum-encoding-helpers.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-enum-with-guard.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-enums-with-same-base-name.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-input-with-guard.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-input-with-vector-members.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-inputs-with-flags.json-TestReplayInputs.h: |
| * replay/scripts/tests/expected/generate-memoized-type-modes.json-TestReplayInputs.h: |
| Rebaseline. |
| |
| 2016-09-28 Filip Pizlo <fpizlo@apple.com> |
| |
| Store-load fences should be a lot cheaper on ARM |
| https://bugs.webkit.org/show_bug.cgi?id=162461 |
| |
| Rubber stamped by Keith Miller. |
| |
| It turns out that they are already cheap enough, so this change just make us use them. |
| |
| * heap/SlotVisitor.cpp: |
| (JSC::SlotVisitor::visitChildren): |
| |
| 2016-09-28 Ryan Haddad <ryanhaddad@apple.com> |
| |
| Unreviewed, rolling out r206522. |
| |
| Roll r206506 back in since the build fix landed in r206521 |
| |
| Reverted changeset: |
| |
| "Unreviewed, rolling out r206506." |
| https://bugs.webkit.org/show_bug.cgi?id=162682 |
| http://trac.webkit.org/changeset/206522 |
| |
| 2016-09-28 Commit Queue <commit-queue@webkit.org> |
| |
| Unreviewed, rolling out r206506. |
| https://bugs.webkit.org/show_bug.cgi?id=162682 |
| |
| Broke the Windows and WinCairo builds. (Requested by |
| ryanhaddad on #webkit). |
| |
| Reverted changeset: |
| |
| "Adopt #pragma once in JavaScriptCore" |
| https://bugs.webkit.org/show_bug.cgi?id=162664 |
| http://trac.webkit.org/changeset/206506 |
| |
| 2016-09-28 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Adopt #pragma once in JavaScriptCore |
| https://bugs.webkit.org/show_bug.cgi?id=162664 |
| |
| Reviewed by Saam Barati. |
| |
| * **/**.h: |
| Adopt pragma once in all but API headers and generated headers. |
| Include some namespace closing comments for consistency. |
| |
| 2016-09-27 JF Bastien <jfbastien@apple.com> |
| |
| Missing Atomics.h include in MarkedBlock.h |
| https://bugs.webkit.org/show_bug.cgi?id=162648 |
| |
| Missing include from my previous patch. |
| |
| Reviewed by Yusuke Suzuki. |
| |
| * heap/MarkedBlock.h: |
| |
| 2016-09-27 Mark Lam <mark.lam@apple.com> |
| |
| createError() and JSObject::calculatedClassName() should not throw any exceptions. |
| https://bugs.webkit.org/show_bug.cgi?id=162637 |
| |
| Reviewed by Geoffrey Garen. |
| |
| * runtime/ExceptionHelpers.cpp: |
| (JSC::createError): |
| - assert that errorDescriptionForValue() did not throw an exception. |
| |
| * runtime/JSObject.cpp: |
| (JSC::JSObject::calculatedClassName): |
| - the code already ensures that we always return a non-null String. Just need to |
| make sure that it catches its own exceptions. |
| |
| 2016-09-27 Filip Pizlo <fpizlo@apple.com> |
| |
| B3::lowerMacros forgets to before->updatePredecessorsAfter() when lowering ChillMod on ARM64 |
| https://bugs.webkit.org/show_bug.cgi?id=162644 |
| |
| Reviewed by Keith Miller. |
| |
| If you forget to update the predecessors of your successors, then bad things will happen if you |
| do something that requires accurate predecessors for correctness. lowerMacros() uses |
| BlockInsertionSet, which relies on accurate predecessors. |
| |
| * b3/B3LowerMacros.cpp: |
| |
| 2016-09-27 JF Bastien <jfbastien@apple.com> |
| |
| Speed up Heap::isMarkedConcurrently |
| https://bugs.webkit.org/show_bug.cgi?id=162095 |
| |
| Reviewed by Filip Pizlo. |
| |
| Speed up isMarkedConcurrently by using WTF::consumeLoad. |
| |
| * heap/MarkedBlock.h: |
| (JSC::MarkedBlock::areMarksStale): |
| (JSC::MarkedBlock::areMarksStaleWithDependency): |
| (JSC::MarkedBlock::isMarkedConcurrently): do away with the load-load fence |
| |
| 2016-09-27 Mark Lam <mark.lam@apple.com> |
| |
| Add some needed CatchScopes in code that should not throw. |
| https://bugs.webkit.org/show_bug.cgi?id=162584 |
| |
| Reviewed by Keith Miller. |
| |
| Re-landing minus the jsc.cpp and ExceptionHelpers.cpp changes. I'll address |
| those in a subsequent patch if the need manifests again in my testing. |
| |
| * API/JSObjectRef.cpp: |
| (JSObjectSetProperty): |
| - This function already handles exceptions in its own way. We're honoring this |
| contract and catching exceptions and passing it to the handler. |
| |
| * interpreter/Interpreter.cpp: |
| (JSC::notifyDebuggerOfUnwinding): |
| - The debugger should not be throwing any exceptions. |
| |
| * profiler/ProfilerDatabase.cpp: |
| (JSC::Profiler::Database::save): |
| - If an exception was thrown while saving the database, there's nothing we can |
| really do about it anyway. Just fail nicely and return false. This is in line |
| with existing error checking code in Database::save() that returns false if |
| it's not able to open the file to save to. |
| |
| * runtime/JSModuleLoader.cpp: |
| (JSC::JSModuleLoader::finishCreation): |
| - The existing code already RELEASE_ASSERT that no exception was thrown. |
| Hence, it's appropriate to use a CatchScope here. |
| |
| * runtime/SamplingProfiler.cpp: |
| (JSC::SamplingProfiler::StackFrame::nameFromCallee): |
| - The sampling profiler is doing a VMInquiry get here. It should never throw an |
| exception. Hence, we'll just use a CatchScope and assert accordingly. |
| |
| 2016-09-27 Jer Noble <jer.noble@apple.com> |
| |
| Remove deprecated ENCRYPTED_MEDIA implementation. |
| https://bugs.webkit.org/show_bug.cgi?id=161010 |
| |
| Reviewed by Eric Carlson. |
| |
| Remove ENABLE_ENCRYPTED_MEDIA. |
| |
| * Configurations/FeatureDefines.xcconfig: |
| |
| 2016-09-27 Michael Catanzaro <mcatanzaro@igalia.com> |
| |
| [GTK] Install binaries to pkglibexecdir rather than bindir |
| https://bugs.webkit.org/show_bug.cgi?id=162602 |
| |
| Reviewed by Carlos Garcia Campos. |
| |
| Install jsc shell to LIBEXEC_INSTALL_DIR rather than EXEC_INSTALL_DIR. |
| |
| Note these locations are the same on non-GTK ports. |
| |
| * shell/CMakeLists.txt: |
| |
| 2016-09-26 Sam Weinig <sam@webkit.org> |
| |
| Make DFGSlowPathGenerator a bit more variadic |
| https://bugs.webkit.org/show_bug.cgi?id=162378 |
| |
| Reviewed by Filip Pizlo. |
| |
| Make the subclass of CallSlowPathGenerator that takes arguments variadic |
| so it can take any number of arguments. Also updates the slowPathCall helper |
| function to be variadic. I had to move the spill mode and exception check |
| requirement parameters to before the arguments since the variadic arguments |
| must be at the end. As a convenience, I added an overload of slowPathCall that |
| doesn't take spill mode and exception check requirement parameters. |
| |
| * dfg/DFGSlowPathGenerator.h: |
| (JSC::DFG::CallResultAndArgumentsSlowPathGenerator::CallResultAndArgumentsSlowPathGenerator): |
| (JSC::DFG::CallResultAndArgumentsSlowPathGenerator::unpackAndGenerate): |
| (JSC::DFG::slowPathCall): |
| (JSC::DFG::CallResultAndNoArgumentsSlowPathGenerator::CallResultAndNoArgumentsSlowPathGenerator): Deleted. |
| (JSC::DFG::CallResultAndOneArgumentSlowPathGenerator::CallResultAndOneArgumentSlowPathGenerator): Deleted. |
| (JSC::DFG::CallResultAndTwoArgumentsSlowPathGenerator::CallResultAndTwoArgumentsSlowPathGenerator): Deleted. |
| (JSC::DFG::CallResultAndThreeArgumentsSlowPathGenerator::CallResultAndThreeArgumentsSlowPathGenerator): Deleted. |
| (JSC::DFG::CallResultAndFourArgumentsSlowPathGenerator::CallResultAndFourArgumentsSlowPathGenerator): Deleted. |
| (JSC::DFG::CallResultAndFourArgumentsSlowPathGenerator::generateInternal): Deleted. |
| (JSC::DFG::CallResultAndFiveArgumentsSlowPathGenerator::CallResultAndFiveArgumentsSlowPathGenerator): Deleted. |
| (JSC::DFG::CallResultAndFiveArgumentsSlowPathGenerator::generateInternal): Deleted. |
| * dfg/DFGSpeculativeJIT.cpp: |
| (JSC::DFG::SpeculativeJIT::compileValueToInt32): |
| (JSC::DFG::SpeculativeJIT::compileNotifyWrite): |
| * dfg/DFGSpeculativeJIT64.cpp: |
| (JSC::DFG::SpeculativeJIT::cachedGetById): |
| |
| 2016-09-26 Commit Queue <commit-queue@webkit.org> |
| |
| Unreviewed, rolling out r206405. |
| https://bugs.webkit.org/show_bug.cgi?id=162588 |
| |
| This change caused LayoutTest crashes. (Requested by |
| ryanhaddad on #webkit). |
| |
| Reverted changeset: |
| |
| "Add some needed CatchScopes in code that should not throw." |
| https://bugs.webkit.org/show_bug.cgi?id=162584 |
| http://trac.webkit.org/changeset/206405 |
| |
| 2016-09-26 Mark Lam <mark.lam@apple.com> |
| |
| Add some needed CatchScopes in code that should not throw. |
| https://bugs.webkit.org/show_bug.cgi?id=162584 |
| |
| Reviewed by Keith Miller. |
| |
| * API/JSObjectRef.cpp: |
| (JSObjectSetProperty): |
| - This function already handles exceptions in its own way. We're honoring this |
| contract and catching exceptions and passing it to the handler. |
| |
| * interpreter/Interpreter.cpp: |
| (JSC::notifyDebuggerOfUnwinding): |
| - The debugger should not be throwing any exceptions. |
| |
| * jsc.cpp: |
| (runJSC): |
| - the buck stops here. There's no reason an exception should propagate past here. |
| |
| * profiler/ProfilerDatabase.cpp: |
| (JSC::Profiler::Database::save): |
| - If an exception was thrown while saving the database, there's nothing we can |
| really do about it anyway. Just fail nicely and return false. This is in line |
| with existing error checking code in Database::save() that returns false if |
| it's not able to open the file to save to. |
| |
| * runtime/ExceptionHelpers.cpp: |
| (JSC::createError): |
| - If we're not able to stringify the error value, then we'll just use the |
| provided message as the error string. It doesn't make sense to have the |
| Error factory throw an exception that shadows the intended exception that the |
| client probably wants to throw (assuming that that's why the client is creating |
| this Error object). |
| |
| * runtime/JSModuleLoader.cpp: |
| (JSC::JSModuleLoader::finishCreation): |
| - The existing code already RELEASE_ASSERT that no exception was thrown. |
| Hence, it's appropriate to use a CatchScope here. |
| |
| * runtime/SamplingProfiler.cpp: |
| (JSC::SamplingProfiler::StackFrame::nameFromCallee): |
| - The sampling profiler is doing a VMInquiry get here. It should never throw an |
| exception. Hence, we'll just use a CatchScope and assert accordingly. |
| |
| 2016-09-26 Mark Lam <mark.lam@apple.com> |
| |
| Exception unwinding code should use a CatchScope instead of a ThrowScope. |
| https://bugs.webkit.org/show_bug.cgi?id=162583 |
| |
| Reviewed by Geoffrey Garen. |
| |
| This is because the exception unwinding code does not throw an exception. |
| It only inspects the thrown exception and passes it to the appropriate handler. |
| |
| * interpreter/Interpreter.cpp: |
| (JSC::Interpreter::unwind): |
| * jit/JITExceptions.cpp: |
| (JSC::genericUnwind): |
| |
| 2016-09-26 Joseph Pecoraro <pecoraro@apple.com> |
| |
| Add an Option to disable the CodeCache |
| https://bugs.webkit.org/show_bug.cgi?id=162579 |
| |
| Reviewed by Geoffrey Garen. |
| |
| * runtime/CodeCache.cpp: |
| (JSC::CodeCache::getGlobalCodeBlock): |
| (JSC::CodeCache::getFunctionExecutableFromGlobalCode): |
| Do not use the cache if the Option is disabled. |
| |
| * runtime/Options.h: |
| New option to not use the code cache. |
| |
| 2016-09-26 Daniel Bates <dabates@apple.com> |
| |
| Rename IOS_TEXT_AUTOSIZING to TEXT_AUTOSIZING |
| https://bugs.webkit.org/show_bug.cgi?id=162365 |
| |
| Reviewed by Simon Fraser. |
| |
| * Configurations/FeatureDefines.xcconfig: |
| |
| 2016-09-26 Benjamin Poulain <benjamin@webkit.org> |
| |
| [JSC] Shrink the Math inline caches some more |
| https://bugs.webkit.org/show_bug.cgi?id=162485 |
| |
| Reviewed by Saam Barati. |
| |
| This patch applies some lessons learnt from op_negate |
| to shrink the generated asm of the previous 3 inline |
| caches. |
| |
| In order of importance: |
| -We do not need to pass the pointer to ArithProfile |
| on the slow path. We can just get the profile out |
| of the Math IC. |
| This saves us from materializing a 64bits value |
| in a register before the call on the slow path. |
| -We can remove a bunch of mov by setting up the registers |
| in the way the slow path needs them. |
| The slow path makes a function calls with the input |
| as second and third arguments, and return the result in |
| the "return register". By using those as target when |
| loading/storing from the stack, we remove 3 mov per slow path. |
| -When performing integer add, we can set the result directly in |
| the output register if that does not trashes one of the input |
| register. This removes one mov per integer add. |
| |
| The inline cache average sizes on Sunspider change as follow: |
| -Adds: 147.573099->131.555556 (~10%) |
| -Muls: 186.882353->170.991597 (~8%) |
| -Subs: 139.127907->121.523256 (~12%) |
| |
| * jit/JIT.h: |
| * jit/JITAddGenerator.cpp: |
| (JSC::JITAddGenerator::generateInline): |
| (JSC::JITAddGenerator::generateFastPath): |
| * jit/JITArithmetic.cpp: |
| (JSC::JIT::emitMathICFast): |
| (JSC::JIT::emitMathICSlow): |
| * jit/JITInlines.h: |
| (JSC::JIT::callOperation): Deleted. |
| * jit/JITOperations.cpp: |
| * jit/JITOperations.h: |
| |
| 2016-09-26 Mark Lam <mark.lam@apple.com> |
| |
| Added RETURN_IF_EXCEPTION() macro and use it for exception checks. |
| https://bugs.webkit.org/show_bug.cgi?id=162521 |
| |
| Reviewed by Saam Barati. |
| |
| Also, where possible, if the return type is JSValue, changed the returned value |
| (on exception) to the empty JSValue (instead of sometimes jsUndefined, jsNull, |
| or the thrown exception value). |
| |
| There are a few places where I had to continue to return the previously returned |
| value (instead of the empty JSValue) in order for tests to pass. This is needed |
| because there are missing exception checks that will need to be added before I |
| can change those to return the empty JSValue too. Identifying all the places |
| where those checks need to be added is beyond the scope of this patch. I will |
| work on adding missing exception checks in a subsequent patch. |
| |
| In this patch, there is one missing exception check in replaceUsingRegExpSearch() |
| that was easily identified, and is necessary so that Interpreter::execute() |
| functions can return JSValue. I've added this missing check. |
| |
| This patch has passed the JSC and layout tests. |
| |
| * dfg/DFGOperations.cpp: |
| (JSC::DFG::operationPutByValInternal): |
| * inspector/JSInjectedScriptHost.cpp: |
| (Inspector::JSInjectedScriptHost::evaluateWithScopeExtension): |
| (Inspector::JSInjectedScriptHost::getInternalProperties): |
| (Inspector::JSInjectedScriptHost::weakMapEntries): |
| (Inspector::JSInjectedScriptHost::weakSetEntries): |
| (Inspector::JSInjectedScriptHost::iteratorEntries): |
| * inspector/JSJavaScriptCallFrame.cpp: |
| (Inspector::JSJavaScriptCallFrame::evaluateWithScopeExtension): |
| * interpreter/Interpreter.cpp: |
| (JSC::eval): |
| (JSC::sizeOfVarargs): |
| (JSC::Interpreter::execute): |
| (JSC::Interpreter::executeCall): |
| (JSC::Interpreter::executeConstruct): |
| * interpreter/ShadowChicken.cpp: |
| (JSC::ShadowChicken::functionsOnStack): |
| * jit/JITOperations.cpp: |
| (JSC::getByVal): |
| * jsc.cpp: |
| (WTF::ImpureGetter::getOwnPropertySlot): |
| (functionRun): |
| (functionRunString): |
| (functionLoad): |
| (functionLoadString): |
| (functionReadFile): |
| (functionCheckSyntax): |
| (functionSetRandomSeed): |
| (functionLoadModule): |
| (functionCreateBuiltin): |
| (functionCheckModuleSyntax): |
| * llint/LLIntSlowPaths.cpp: |
| (JSC::LLInt::getByVal): |
| (JSC::LLInt::LLINT_SLOW_PATH_DECL): |
| * profiler/ProfilerBytecodeSequence.cpp: |
| (JSC::Profiler::BytecodeSequence::addSequenceProperties): |
| * profiler/ProfilerCompilation.cpp: |
| (JSC::Profiler::Compilation::toJS): |
| * profiler/ProfilerDatabase.cpp: |
| (JSC::Profiler::Database::toJS): |
| * profiler/ProfilerOSRExitSite.cpp: |
| (JSC::Profiler::OSRExitSite::toJS): |
| * profiler/ProfilerOriginStack.cpp: |
| (JSC::Profiler::OriginStack::toJS): |
| * runtime/ArrayPrototype.cpp: |
| (JSC::speciesConstructArray): |
| (JSC::shift): |
| (JSC::unshift): |
| (JSC::arrayProtoFuncToString): |
| (JSC::arrayProtoFuncToLocaleString): |
| (JSC::slowJoin): |
| (JSC::fastJoin): |
| (JSC::arrayProtoFuncJoin): |
| (JSC::arrayProtoFuncPop): |
| (JSC::arrayProtoFuncPush): |
| (JSC::arrayProtoFuncReverse): |
| (JSC::arrayProtoFuncShift): |
| (JSC::arrayProtoFuncSlice): |
| (JSC::arrayProtoFuncSplice): |
| (JSC::arrayProtoFuncUnShift): |
| (JSC::arrayProtoFuncIndexOf): |
| (JSC::arrayProtoFuncLastIndexOf): |
| (JSC::moveElements): |
| (JSC::arrayProtoPrivateFuncConcatMemcpy): |
| * runtime/BooleanConstructor.cpp: |
| (JSC::constructWithBooleanConstructor): |
| * runtime/CommonSlowPaths.h: |
| (JSC::CommonSlowPaths::opIn): |
| * runtime/Completion.cpp: |
| (JSC::loadAndEvaluateModule): |
| (JSC::loadModule): |
| * runtime/ConsoleObject.cpp: |
| (JSC::consoleProtoFuncAssert): |
| (JSC::consoleProtoFuncProfile): |
| (JSC::consoleProtoFuncProfileEnd): |
| (JSC::consoleProtoFuncTakeHeapSnapshot): |
| (JSC::consoleProtoFuncTime): |
| (JSC::consoleProtoFuncTimeEnd): |
| * runtime/DateConstructor.cpp: |
| (JSC::constructDate): |
| (JSC::dateParse): |
| * runtime/DatePrototype.cpp: |
| (JSC::dateProtoFuncToPrimitiveSymbol): |
| (JSC::dateProtoFuncToJSON): |
| * runtime/ErrorConstructor.cpp: |
| (JSC::Interpreter::constructWithErrorConstructor): |
| * runtime/ErrorInstance.cpp: |
| (JSC::ErrorInstance::sanitizedToString): |
| * runtime/ErrorPrototype.cpp: |
| (JSC::errorProtoFuncToString): |
| * runtime/ExceptionScope.h: |
| * runtime/FunctionConstructor.cpp: |
| (JSC::constructFunctionSkippingEvalEnabledCheck): |
| * runtime/GenericArgumentsInlines.h: |
| (JSC::GenericArguments<Type>::copyToArguments): |
| * runtime/GetterSetter.cpp: |
| (JSC::callGetter): |
| * runtime/HashMapImpl.h: |
| (JSC::jsMapHash): |
| (JSC::HashMapImpl::finishCreation): |
| (JSC::HashMapImpl::findBucket): |
| (JSC::HashMapImpl::add): |
| (JSC::HashMapImpl::rehash): |
| * runtime/InspectorInstrumentationObject.cpp: |
| (JSC::inspectorInstrumentationObjectLog): |
| * runtime/InternalFunction.cpp: |
| (JSC::InternalFunction::createSubclassStructure): |
| * runtime/IntlCollator.cpp: |
| (JSC::IntlCollator::initializeCollator): |
| * runtime/IntlCollatorConstructor.cpp: |
| (JSC::constructIntlCollator): |
| (JSC::IntlCollatorConstructorFuncSupportedLocalesOf): |
| * runtime/IntlCollatorPrototype.cpp: |
| (JSC::IntlCollatorFuncCompare): |
| (JSC::IntlCollatorPrototypeGetterCompare): |
| * runtime/IntlDateTimeFormat.cpp: |
| (JSC::toDateTimeOptionsAnyDate): |
| (JSC::IntlDateTimeFormat::initializeDateTimeFormat): |
| * runtime/IntlDateTimeFormatConstructor.cpp: |
| (JSC::constructIntlDateTimeFormat): |
| (JSC::IntlDateTimeFormatConstructorFuncSupportedLocalesOf): |
| * runtime/IntlDateTimeFormatPrototype.cpp: |
| (JSC::IntlDateTimeFormatFuncFormatDateTime): |
| (JSC::IntlDateTimeFormatPrototypeGetterFormat): |
| * runtime/IntlNumberFormat.cpp: |
| (JSC::IntlNumberFormat::initializeNumberFormat): |
| * runtime/IntlNumberFormatConstructor.cpp: |
| (JSC::constructIntlNumberFormat): |
| (JSC::IntlNumberFormatConstructorFuncSupportedLocalesOf): |
| * runtime/IntlNumberFormatPrototype.cpp: |
| (JSC::IntlNumberFormatFuncFormatNumber): |
| (JSC::IntlNumberFormatPrototypeGetterFormat): |
| * runtime/IntlObject.cpp: |
| (JSC::intlBooleanOption): |
| (JSC::intlStringOption): |
| (JSC::intlNumberOption): |
| (JSC::canonicalizeLocaleList): |
| (JSC::supportedLocales): |
| * runtime/IntlObjectInlines.h: |
| (JSC::constructIntlInstanceWithWorkaroundForLegacyIntlConstructor): |
| * runtime/IteratorOperations.cpp: |
| (JSC::iteratorNext): |
| (JSC::iteratorStep): |
| (JSC::iteratorClose): |
| (JSC::iteratorForIterable): |
| * runtime/IteratorOperations.h: |
| (JSC::forEachInIterable): |
| * runtime/JSArray.cpp: |
| (JSC::JSArray::pop): |
| (JSC::JSArray::copyToArguments): |
| * runtime/JSArrayBufferConstructor.cpp: |
| (JSC::constructArrayBuffer): |
| * runtime/JSArrayBufferPrototype.cpp: |
| (JSC::arrayBufferProtoFuncSlice): |
| * runtime/JSArrayInlines.h: |
| (JSC::getLength): |
| (JSC::toLength): |
| * runtime/JSBoundFunction.cpp: |
| (JSC::getBoundFunctionStructure): |
| (JSC::JSBoundFunction::create): |
| * runtime/JSCJSValue.cpp: |
| (JSC::JSValue::putToPrimitive): |
| (JSC::JSValue::toStringSlowCase): |
| * runtime/JSCJSValueInlines.h: |
| (JSC::toPreferredPrimitiveType): |
| (JSC::JSValue::getPropertySlot): |
| (JSC::JSValue::equalSlowCaseInline): |
| * runtime/JSDataViewPrototype.cpp: |
| (JSC::getData): |
| (JSC::setData): |
| * runtime/JSFunction.cpp: |
| (JSC::JSFunction::setFunctionName): |
| * runtime/JSGenericTypedArrayView.h: |
| (JSC::JSGenericTypedArrayView::setIndex): |
| * runtime/JSGenericTypedArrayViewConstructorInlines.h: |
| (JSC::constructGenericTypedArrayViewFromIterator): |
| (JSC::constructGenericTypedArrayViewWithArguments): |
| (JSC::constructGenericTypedArrayView): |
| * runtime/JSGenericTypedArrayViewPrototypeFunctions.h: |
| (JSC::speciesConstruct): |
| (JSC::genericTypedArrayViewProtoFuncSet): |
| (JSC::genericTypedArrayViewProtoFuncCopyWithin): |
| (JSC::genericTypedArrayViewProtoFuncIncludes): |
| (JSC::genericTypedArrayViewProtoFuncIndexOf): |
| (JSC::genericTypedArrayViewProtoFuncJoin): |
| (JSC::genericTypedArrayViewProtoFuncLastIndexOf): |
| (JSC::genericTypedArrayViewProtoFuncSlice): |
| (JSC::genericTypedArrayViewPrivateFuncSubarrayCreate): |
| * runtime/JSGlobalObject.h: |
| (JSC::constructEmptyArray): |
| (JSC::constructArray): |
| (JSC::constructArrayNegativeIndexed): |
| * runtime/JSGlobalObjectFunctions.cpp: |
| (JSC::globalFuncEval): |
| * runtime/JSModuleRecord.cpp: |
| (JSC::JSModuleRecord::instantiateDeclarations): |
| * runtime/JSONObject.cpp: |
| (JSC::Stringifier::stringify): |
| (JSC::Stringifier::toJSON): |
| (JSC::Stringifier::appendStringifiedValue): |
| (JSC::Stringifier::Holder::appendNextProperty): |
| (JSC::Walker::walk): |
| (JSC::JSONProtoFuncParse): |
| * runtime/JSObject.cpp: |
| (JSC::ordinarySetSlow): |
| (JSC::JSObject::setPrototypeWithCycleCheck): |
| (JSC::callToPrimitiveFunction): |
| (JSC::JSObject::defaultHasInstance): |
| (JSC::JSObject::getPropertyNames): |
| (JSC::JSObject::toNumber): |
| (JSC::JSObject::toString): |
| (JSC::JSObject::defineOwnNonIndexProperty): |
| (JSC::JSObject::getGenericPropertyNames): |
| (JSC::JSObject::getMethod): |
| * runtime/JSObjectInlines.h: |
| (JSC::createListFromArrayLike): |
| (JSC::JSObject::getPropertySlot): |
| (JSC::JSObject::getNonIndexPropertySlot): |
| * runtime/JSPromiseConstructor.cpp: |
| (JSC::constructPromise): |
| * runtime/JSPromiseDeferred.cpp: |
| (JSC::JSPromiseDeferred::create): |
| * runtime/JSPropertyNameEnumerator.h: |
| (JSC::propertyNameEnumerator): |
| * runtime/JSPropertyNameIterator.cpp: |
| (JSC::JSPropertyNameIterator::create): |
| * runtime/JSScope.cpp: |
| (JSC::isUnscopable): |
| * runtime/JSString.cpp: |
| (JSC::JSString::equalSlowCase): |
| * runtime/JSStringJoiner.cpp: |
| (JSC::JSStringJoiner::join): |
| * runtime/LiteralParser.cpp: |
| (JSC::LiteralParser<CharType>::parse): |
| * runtime/MapBase.h: |
| (JSC::MapBase::finishCreation): |
| * runtime/MapConstructor.cpp: |
| (JSC::constructMap): |
| * runtime/MathObject.cpp: |
| (JSC::mathProtoFuncClz32): |
| (JSC::mathProtoFuncHypot): |
| (JSC::mathProtoFuncIMul): |
| * runtime/ModuleLoaderPrototype.cpp: |
| (JSC::moduleLoaderPrototypeParseModule): |
| (JSC::moduleLoaderPrototypeRequestedModules): |
| (JSC::moduleLoaderPrototypeModuleDeclarationInstantiation): |
| * runtime/NativeErrorConstructor.cpp: |
| (JSC::Interpreter::constructWithNativeErrorConstructor): |
| * runtime/NumberConstructor.cpp: |
| (JSC::constructWithNumberConstructor): |
| * runtime/ObjectConstructor.cpp: |
| (JSC::constructObject): |
| (JSC::objectConstructorGetPrototypeOf): |
| (JSC::objectConstructorSetPrototypeOf): |
| (JSC::objectConstructorGetOwnPropertyDescriptor): |
| (JSC::objectConstructorGetOwnPropertyDescriptors): |
| (JSC::objectConstructorGetOwnPropertyNames): |
| (JSC::objectConstructorGetOwnPropertySymbols): |
| (JSC::objectConstructorKeys): |
| (JSC::ownEnumerablePropertyKeys): |
| (JSC::toPropertyDescriptor): |
| (JSC::objectConstructorDefineProperty): |
| (JSC::defineProperties): |
| (JSC::objectConstructorSeal): |
| (JSC::objectConstructorFreeze): |
| (JSC::objectConstructorIsSealed): |
| (JSC::objectConstructorIsFrozen): |
| (JSC::objectConstructorIsExtensible): |
| (JSC::ownPropertyKeys): |
| * runtime/ObjectConstructor.h: |
| (JSC::constructObjectFromPropertyDescriptor): |
| * runtime/ObjectPrototype.cpp: |
| (JSC::objectProtoFuncHasOwnProperty): |
| (JSC::objectProtoFuncIsPrototypeOf): |
| (JSC::objectProtoFuncDefineGetter): |
| (JSC::objectProtoFuncDefineSetter): |
| (JSC::objectProtoFuncLookupGetter): |
| (JSC::objectProtoFuncLookupSetter): |
| (JSC::objectProtoFuncPropertyIsEnumerable): |
| (JSC::objectProtoFuncToLocaleString): |
| (JSC::objectProtoFuncToString): |
| * runtime/Operations.cpp: |
| (JSC::jsAddSlowCase): |
| * runtime/PropertyDescriptor.cpp: |
| (JSC::PropertyDescriptor::slowGetterSetter): |
| * runtime/ProxyConstructor.cpp: |
| (JSC::makeRevocableProxy): |
| * runtime/ProxyObject.cpp: |
| (JSC::performProxyGet): |
| (JSC::ProxyObject::performGet): |
| (JSC::ProxyObject::performInternalMethodGetOwnProperty): |
| (JSC::ProxyObject::performHasProperty): |
| (JSC::ProxyObject::performPut): |
| (JSC::ProxyObject::putByIndexCommon): |
| (JSC::performProxyCall): |
| (JSC::performProxyConstruct): |
| (JSC::ProxyObject::performDelete): |
| (JSC::ProxyObject::performPreventExtensions): |
| (JSC::ProxyObject::performIsExtensible): |
| (JSC::ProxyObject::performDefineOwnProperty): |
| (JSC::ProxyObject::performGetOwnPropertyNames): |
| (JSC::ProxyObject::performSetPrototype): |
| (JSC::ProxyObject::performGetPrototype): |
| * runtime/ReflectObject.cpp: |
| (JSC::reflectObjectConstruct): |
| (JSC::reflectObjectDefineProperty): |
| (JSC::reflectObjectGet): |
| (JSC::reflectObjectGetOwnPropertyDescriptor): |
| (JSC::reflectObjectIsExtensible): |
| (JSC::reflectObjectPreventExtensions): |
| (JSC::reflectObjectSet): |
| (JSC::reflectObjectSetPrototypeOf): |
| * runtime/RegExpConstructor.cpp: |
| (JSC::toFlags): |
| (JSC::regExpCreate): |
| (JSC::constructRegExp): |
| * runtime/RegExpConstructor.h: |
| (JSC::isRegExp): |
| * runtime/RegExpObject.cpp: |
| (JSC::collectMatches): |
| (JSC::RegExpObject::matchGlobal): |
| * runtime/RegExpPrototype.cpp: |
| (JSC::regExpProtoFuncCompile): |
| (JSC::flagsString): |
| (JSC::regExpProtoFuncToString): |
| (JSC::regExpProtoGetterFlags): |
| (JSC::regExpProtoFuncSearchFast): |
| (JSC::regExpProtoFuncSplitFast): |
| * runtime/SetConstructor.cpp: |
| (JSC::constructSet): |
| * runtime/StringConstructor.cpp: |
| (JSC::stringFromCodePoint): |
| (JSC::constructWithStringConstructor): |
| * runtime/StringObject.cpp: |
| (JSC::StringObject::defineOwnProperty): |
| * runtime/StringPrototype.cpp: |
| (JSC::replaceUsingRegExpSearch): |
| (JSC::operationStringProtoFuncReplaceRegExpEmptyStr): |
| (JSC::replaceUsingStringSearch): |
| (JSC::replace): |
| (JSC::stringProtoFuncReplaceUsingRegExp): |
| (JSC::stringProtoFuncReplaceUsingStringSearch): |
| (JSC::stringProtoFuncCodePointAt): |
| (JSC::stringProtoFuncSlice): |
| (JSC::stringProtoFuncSplitFast): |
| (JSC::stringProtoFuncSubstr): |
| (JSC::stringProtoFuncSubstring): |
| (JSC::stringProtoFuncLocaleCompare): |
| (JSC::toLocaleCase): |
| (JSC::stringProtoFuncBig): |
| (JSC::stringProtoFuncSmall): |
| (JSC::stringProtoFuncBlink): |
| (JSC::stringProtoFuncBold): |
| (JSC::stringProtoFuncFixed): |
| (JSC::stringProtoFuncItalics): |
| (JSC::stringProtoFuncStrike): |
| (JSC::stringProtoFuncSub): |
| (JSC::stringProtoFuncSup): |
| (JSC::stringProtoFuncFontcolor): |
| (JSC::stringProtoFuncFontsize): |
| (JSC::stringProtoFuncAnchor): |
| (JSC::stringProtoFuncLink): |
| (JSC::trimString): |
| (JSC::stringProtoFuncStartsWith): |
| (JSC::stringProtoFuncEndsWith): |
| (JSC::stringIncludesImpl): |
| (JSC::stringProtoFuncIncludes): |
| (JSC::builtinStringIncludesInternal): |
| (JSC::stringProtoFuncNormalize): |
| * runtime/SymbolConstructor.cpp: |
| (JSC::symbolConstructorFor): |
| * runtime/TemplateRegistry.cpp: |
| (JSC::TemplateRegistry::getTemplateObject): |
| * runtime/WeakMapConstructor.cpp: |
| (JSC::constructWeakMap): |
| * runtime/WeakSetConstructor.cpp: |
| (JSC::constructWeakSet): |
| * tools/JSDollarVMPrototype.cpp: |
| (JSC::functionPrint): |
| |
| 2016-09-26 Don Olmstead <don.olmstead@am.sony.com> |
| |
| [JSC] Allow fixedExecutableMemoryPoolSize to be set during build |
| https://bugs.webkit.org/show_bug.cgi?id=162514 |
| |
| Reviewed by Mark Lam. |
| |
| * jit/ExecutableAllocator.h: |
| |
| == Rolled over to ChangeLog-2016-09-26 == |