diff options
Diffstat (limited to 'Source/JavaScriptCore')
122 files changed, 1173 insertions, 4927 deletions
diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp index c62efc60d..491fa988f 100644 --- a/Source/JavaScriptCore/API/JSObjectRef.cpp +++ b/Source/JavaScriptCore/API/JSObjectRef.cpp @@ -29,9 +29,9 @@ #include "JSObjectRefPrivate.h" #include "APICast.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" #include "CodeBlock.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "DateConstructor.h" #include "ErrorConstructor.h" #include "FunctionConstructor.h" @@ -144,9 +144,9 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa for (size_t i = 0; i < argumentCount; ++i) argList.append(toJS(exec, arguments[i])); - result = constructArray(exec, static_cast<ArrayAllocationProfile*>(0), argList); + result = constructArray(exec, argList); } else - result = constructEmptyArray(exec, 0); + result = constructEmptyArray(exec); if (exec->hadException()) { if (exception) diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt index bfaca5673..393db67c3 100644 --- a/Source/JavaScriptCore/CMakeLists.txt +++ b/Source/JavaScriptCore/CMakeLists.txt @@ -40,7 +40,6 @@ SET(JavaScriptCore_SOURCES assembler/MacroAssembler.cpp assembler/LinkBuffer.cpp - bytecode/ArrayAllocationProfile.cpp bytecode/ArrayProfile.cpp bytecode/CallLinkInfo.cpp bytecode/CallLinkStatus.cpp diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index dbe22d11e..320b1cfbe 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,659 +1,3 @@ -2012-11-09 Csaba Osztrogonác <ossy@webkit.org> - - [Qt] Fix the LLINT build from ARMv7 platform - https://bugs.webkit.org/show_bug.cgi?id=101712 - - Reviewed by Simon Hausmann. - - Enable generating of LLIntAssembly.h on ARM platforms. - - * DerivedSources.pri: - * JavaScriptCore.pro: - -2012-11-08 Filip Pizlo <fpizlo@apple.com> - - ArrayPrototype.h should have correct indentation - - Rubber stamped by Sam Weinig. - - * runtime/ArrayPrototype.h: - -2012-11-08 Mark Lam <mark.lam@apple.com> - - Renamed ...InlineMethods.h files to ...Inlines.h. - https://bugs.webkit.org/show_bug.cgi?id=101145. - - Reviewed by Geoffrey Garen. - - This is only a refactoring effort to rename the files. There are no - functionality changes. - - * API/JSObjectRef.cpp: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/CodeBlock.cpp: - * dfg/DFGOperations.cpp: - * heap/ConservativeRoots.cpp: - * heap/CopiedBlock.h: - * heap/CopiedSpace.cpp: - * heap/CopiedSpaceInlineMethods.h: Removed. - * heap/CopiedSpaceInlines.h: Copied from Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h. - * heap/CopyVisitor.cpp: - * heap/CopyVisitorInlineMethods.h: Removed. - * heap/CopyVisitorInlines.h: Copied from Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h. - * heap/GCThread.cpp: - * heap/GCThreadSharedData.cpp: - * heap/HandleStack.cpp: - * heap/Heap.cpp: - * heap/HeapRootVisitor.h: - * heap/MarkStack.cpp: - * heap/MarkStackInlineMethods.h: Removed. - * heap/MarkStackInlines.h: Copied from Source/JavaScriptCore/heap/MarkStackInlineMethods.h. - * heap/SlotVisitor.cpp: - * heap/SlotVisitor.h: - * heap/SlotVisitorInlineMethods.h: Removed. - * heap/SlotVisitorInlines.h: Copied from Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h. - * jit/HostCallReturnValue.cpp: - * jit/JIT.cpp: - * jit/JITArithmetic.cpp: - * jit/JITArithmetic32_64.cpp: - * jit/JITCall.cpp: - * jit/JITCall32_64.cpp: - * jit/JITInlineMethods.h: Removed. - * jit/JITInlines.h: Copied from Source/JavaScriptCore/jit/JITInlineMethods.h. - * jit/JITOpcodes.cpp: - * jit/JITOpcodes32_64.cpp: - * jit/JITPropertyAccess.cpp: - * jit/JITPropertyAccess32_64.cpp: - * jsc.cpp: - * runtime/ArrayConstructor.cpp: - * runtime/ArrayPrototype.cpp: - * runtime/ButterflyInlineMethods.h: Removed. - * runtime/ButterflyInlines.h: Copied from Source/JavaScriptCore/runtime/ButterflyInlineMethods.h. - * runtime/IndexingHeaderInlineMethods.h: Removed. - * runtime/IndexingHeaderInlines.h: Copied from Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h. - * runtime/JSActivation.h: - * runtime/JSArray.cpp: - * runtime/JSArray.h: - * runtime/JSCell.h: - * runtime/JSObject.cpp: - * runtime/JSValueInlineMethods.h: Removed. - * runtime/JSValueInlines.h: Copied from Source/JavaScriptCore/runtime/JSValueInlineMethods.h. - * runtime/LiteralParser.cpp: - * runtime/ObjectConstructor.cpp: - * runtime/Operations.h: - * runtime/RegExpMatchesArray.cpp: - * runtime/RegExpObject.cpp: - * runtime/StringPrototype.cpp: - -2012-11-08 Filip Pizlo <fpizlo@apple.com> - - ArrayConstructor.h should have correct indentation - - Rubber stamped by Sam Weinig. - - * runtime/ArrayConstructor.h: - -2012-11-08 Filip Pizlo <fpizlo@apple.com> - - DFG should know that int == null is always false - https://bugs.webkit.org/show_bug.cgi?id=101665 - - Reviewed by Oliver Hunt. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - -2012-11-08 Filip Pizlo <fpizlo@apple.com> - - Arguments.h should have correct indentation - - Rubber stamped by Sam Weinig. - - * runtime/Arguments.h: - -2012-11-08 Filip Pizlo <fpizlo@apple.com> - - It should be possible to JIT compile get_by_vals and put_by_vals even if the DFG is disabled. - - Reviewed by Oliver Hunt. - - * jit/JITInlineMethods.h: - (JSC::JIT::chooseArrayMode): - -2012-11-08 Filip Pizlo <fpizlo@apple.com> - - op_call should have LLInt call link info even if the DFG is disabled - https://bugs.webkit.org/show_bug.cgi?id=101672 - - Reviewed by Oliver Hunt. - - Get rid of the evil uses of fall-through. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - -2012-11-08 Oliver Hunt <oliver@apple.com> - - Improve effectiveness of function-level caching - https://bugs.webkit.org/show_bug.cgi?id=101667 - - Reviewed by Filip Pizlo. - - Added a random-eviction based cache for unlinked functions, and switch - UnlinkedFunctionExecutable's code references to Weak<>, thereby letting - us remove the explicit UnlinkedFunctionExecutable::clearCode() calls that - were being triggered by GC. - - Refactored the random eviction part of the CodeCache into a separate data - structure so that I didn't have to duplicate the code again, and then used - that for the new function cache. - - * bytecode/UnlinkedCodeBlock.cpp: - (JSC::UnlinkedFunctionExecutable::visitChildren): - (JSC::UnlinkedFunctionExecutable::codeBlockFor): - * bytecode/UnlinkedCodeBlock.h: - (JSC::UnlinkedFunctionExecutable::clearCodeForRecompilation): - (UnlinkedFunctionExecutable): - * debugger/Debugger.cpp: - * runtime/CodeCache.cpp: - (JSC::CodeCache::getCodeBlock): - (JSC::CodeCache::generateFunctionCodeBlock): - (JSC::CodeCache::getFunctionExecutableFromGlobalCode): - (JSC::CodeCache::usedFunctionCode): - (JSC): - * runtime/Executable.cpp: - (JSC::FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling): - (JSC::FunctionExecutable::clearCode): - * runtime/Executable.h: - (FunctionExecutable): - -2012-11-07 Filip Pizlo <fpizlo@apple.com> - - DFG constant folding and CFG simplification should be smart enough to know that if a logical op's operand is proven to have a non-masquerading structure then it always evaluates to true - https://bugs.webkit.org/show_bug.cgi?id=101511 - - Reviewed by Oliver Hunt. - - To make life easier, this moves BranchDirection into BasicBlock so that after - running the CFA, we always know, for each block, what direction the CFA - proved. CFG simplification now both uses and preserves cfaBranchDirection in - its transformations. - - Also made both LogicalNot and Branch check whether the operand is a known cell - with a known structure, and if so, made them do the appropriate folding. - - 5% speed-up on V8/raytrace because it makes raytrace's own null checks - evaporate (i.e. idioms like 'if (!x) throw "unhappiness"') thanks to the fact - that we were already doing structure check hoisting. - - * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::endBasicBlock): - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::mergeToSuccessors): - * dfg/DFGAbstractState.h: - (AbstractState): - * dfg/DFGBasicBlock.h: - (JSC::DFG::BasicBlock::BasicBlock): - (BasicBlock): - * dfg/DFGBranchDirection.h: Added. - (DFG): - (JSC::DFG::branchDirectionToString): - (JSC::DFG::isKnownDirection): - (JSC::DFG::branchCondition): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::run): - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - -2012-11-08 Christophe Dumez <christophe.dumez@intel.com> - - [JSC] HTML extensions to String.prototype should escape " as " in argument values - https://bugs.webkit.org/show_bug.cgi?id=90667 - - Reviewed by Benjamin Poulain. - - Escape quotation mark as " in argument values to: - - String.prototype.anchor(name) - - String.prototype.fontcolor(color) - - String.prototype.fontsize(size) - - String.prototype.link(href) - - This behavior matches Chromium/V8 and Firefox/Spidermonkey - implementations and is requited by: - http://mathias.html5.org/specs/javascript/#escapeattributevalue - - This also fixes a potential security risk (XSS vector). - - * runtime/StringPrototype.cpp: - (JSC::stringProtoFuncFontcolor): - (JSC::stringProtoFuncFontsize): - (JSC::stringProtoFuncAnchor): - (JSC::stringProtoFuncLink): - -2012-11-08 Anders Carlsson <andersca@apple.com> - - HeapStatistics::s_pauseTimeStarts and s_pauseTimeEnds should be Vectors - https://bugs.webkit.org/show_bug.cgi?id=101651 - - Reviewed by Andreas Kling. - - HeapStatistics uses Deques when Vectors would work just as good. - - * heap/HeapStatistics.cpp: - * heap/HeapStatistics.h: - (HeapStatistics): - -2012-11-07 Filip Pizlo <fpizlo@apple.com> - - DFG should not assume that something is a double just because it might be undefined - https://bugs.webkit.org/show_bug.cgi?id=101438 - - Reviewed by Oliver Hunt. - - This changes all non-bitop arithmetic to (a) statically expect that variables are - defined prior to use in arithmetic and (b) not fall off into double paths just - because a value may not be a number. This is accomplished with two new notions of - speculation: - - shouldSpeculateIntegerExpectingDefined: Should we speculate that the value is an - integer if we ignore undefined (i.e. SpecOther) predictions? - - shouldSpeculateIntegerForArithmetic: Should we speculate that the value is an - integer if we ignore non-numeric predictions? - - This is a ~2x speed-up on programs that seem to our prediction propagator to have - paths in which otherwise numeric variables are undefined. - - * bytecode/SpeculatedType.h: - (JSC::isInt32SpeculationForArithmetic): - (JSC): - (JSC::isInt32SpeculationExpectingDefined): - (JSC::isDoubleSpeculationForArithmetic): - (JSC::isNumberSpeculationExpectingDefined): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::addShouldSpeculateInteger): - (JSC::DFG::Graph::mulShouldSpeculateInteger): - (JSC::DFG::Graph::negateShouldSpeculateInteger): - (JSC::DFG::Graph::addImmediateShouldSpeculateInteger): - (JSC::DFG::Graph::mulImmediateShouldSpeculateInteger): - * dfg/DFGNode.h: - (JSC::DFG::Node::shouldSpeculateIntegerForArithmetic): - (Node): - (JSC::DFG::Node::shouldSpeculateIntegerExpectingDefined): - (JSC::DFG::Node::shouldSpeculateDoubleForArithmetic): - (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileAdd): - (JSC::DFG::SpeculativeJIT::compileArithMod): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITArithmetic.cpp: - (JSC::JIT::emit_op_div): - -2012-11-06 Filip Pizlo <fpizlo@apple.com> - - JSC should infer when indexed storage contains only integers or doubles - https://bugs.webkit.org/show_bug.cgi?id=98606 - - Reviewed by Oliver Hunt. - - This adds two new indexing types: int32 and double. It also adds array allocation profiling, - which allows array allocations to converge to allocating arrays using those types to which - those arrays would have been converted. - - 20% speed-up on navier-stokes. 40% speed-up on various Kraken DSP tests. Some slow-downs too, - but a performance win overall on all benchmarks we track. - - * API/JSObjectRef.cpp: - (JSObjectMakeArray): - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/AbstractMacroAssembler.h: - (JumpList): - (JSC::AbstractMacroAssembler::JumpList::JumpList): - * assembler/MacroAssemblerX86Common.h: - (JSC::MacroAssemblerX86Common::branchDouble): - * assembler/X86Assembler.h: - (JSC::X86Assembler::jnp): - (X86Assembler): - (JSC::X86Assembler::X86InstructionFormatter::emitRex): - * bytecode/ArrayAllocationProfile.cpp: Added. - (JSC): - (JSC::ArrayAllocationProfile::updateIndexingType): - * bytecode/ArrayAllocationProfile.h: Added. - (JSC): - (ArrayAllocationProfile): - (JSC::ArrayAllocationProfile::ArrayAllocationProfile): - (JSC::ArrayAllocationProfile::selectIndexingType): - (JSC::ArrayAllocationProfile::updateLastAllocation): - (JSC::ArrayAllocationProfile::selectIndexingTypeFor): - (JSC::ArrayAllocationProfile::updateLastAllocationFor): - * bytecode/ArrayProfile.cpp: - (JSC::ArrayProfile::updatedObservedArrayModes): - (JSC): - * bytecode/ArrayProfile.h: - (JSC): - (JSC::arrayModesInclude): - (JSC::shouldUseSlowPutArrayStorage): - (JSC::shouldUseFastArrayStorage): - (JSC::shouldUseContiguous): - (JSC::shouldUseDouble): - (JSC::shouldUseInt32): - (ArrayProfile): - * bytecode/ByValInfo.h: - (JSC::isOptimizableIndexingType): - (JSC::jitArrayModeForIndexingType): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::CodeBlock::CodeBlock): - (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): - (JSC): - (JSC::CodeBlock::updateAllValueProfilePredictions): - (JSC::CodeBlock::updateAllArrayPredictions): - (JSC::CodeBlock::updateAllPredictions): - (JSC::CodeBlock::shouldOptimizeNow): - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::numberOfArrayAllocationProfiles): - (JSC::CodeBlock::addArrayAllocationProfile): - (JSC::CodeBlock::updateAllValueProfilePredictions): - (JSC::CodeBlock::updateAllArrayPredictions): - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - * bytecode/Instruction.h: - (JSC): - (JSC::Instruction::Instruction): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/SpeculatedType.h: - (JSC): - (JSC::isRealNumberSpeculation): - * bytecode/UnlinkedCodeBlock.cpp: - (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): - * bytecode/UnlinkedCodeBlock.h: - (JSC): - (JSC::UnlinkedCodeBlock::addArrayAllocationProfile): - (JSC::UnlinkedCodeBlock::numberOfArrayAllocationProfiles): - (UnlinkedCodeBlock): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::newArrayAllocationProfile): - (JSC): - (JSC::BytecodeGenerator::emitNewArray): - (JSC::BytecodeGenerator::emitExpectedFunctionSnippet): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArrayMode.cpp: - (JSC::DFG::ArrayMode::fromObserved): - (JSC::DFG::ArrayMode::refine): - (DFG): - (JSC::DFG::ArrayMode::alreadyChecked): - (JSC::DFG::arrayTypeToString): - * dfg/DFGArrayMode.h: - (JSC::DFG::ArrayMode::withType): - (ArrayMode): - (JSC::DFG::ArrayMode::withTypeAndConversion): - (JSC::DFG::ArrayMode::usesButterfly): - (JSC::DFG::ArrayMode::isSpecific): - (JSC::DFG::ArrayMode::supportsLength): - (JSC::DFG::ArrayMode::arrayModesThatPassFiltering): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::getArrayMode): - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::handleIntrinsic): - (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): - (CCallHelpers): - * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: - (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal): - (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - (JSC::DFG::FixupPhase::checkArray): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::byValIsPure): - * dfg/DFGNode.h: - (NewArrayBufferData): - (JSC::DFG::Node::hasIndexingType): - (Node): - (JSC::DFG::Node::indexingType): - (JSC::DFG::Node::setIndexingType): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::emitAllocateJSArray): - (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode): - (DFG): - (JSC::DFG::SpeculativeJIT::checkArray): - (JSC::DFG::SpeculativeJIT::arrayify): - (JSC::DFG::SpeculativeJIT::compileDoublePutByVal): - (JSC::DFG::SpeculativeJIT::compileGetArrayLength): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (SpeculativeJIT): - (SpeculateIntegerOperand): - (JSC::DFG::SpeculateIntegerOperand::use): - (SpeculateDoubleOperand): - (JSC::DFG::SpeculateDoubleOperand::use): - * dfg/DFGSpeculativeJIT32_64.cpp: - (DFG): - (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JIT.h: - (JSC::JIT::emitInt32GetByVal): - (JIT): - (JSC::JIT::emitInt32PutByVal): - (JSC::JIT::emitDoublePutByVal): - (JSC::JIT::emitContiguousPutByVal): - * jit/JITExceptions.cpp: - (JSC::genericThrow): - * jit/JITInlineMethods.h: - (JSC::arrayProfileSaw): - (JSC::JIT::chooseArrayMode): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_new_array): - (JSC::JIT::emit_op_new_array_with_size): - (JSC::JIT::emit_op_new_array_buffer): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emitDoubleGetByVal): - (JSC): - (JSC::JIT::emitContiguousGetByVal): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::emitGenericContiguousPutByVal): - (JSC::JIT::emitSlow_op_put_by_val): - (JSC::JIT::privateCompileGetByVal): - (JSC::JIT::privateCompilePutByVal): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emitContiguousGetByVal): - (JSC::JIT::emitDoubleGetByVal): - (JSC): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::emitGenericContiguousPutByVal): - (JSC::JIT::emitSlow_op_put_by_val): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * jit/JITStubs.h: - (JSC): - * jsc.cpp: - (GlobalObject::finishCreation): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::jitCompileAndSetHeuristics): - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * offlineasm/x86.rb: - * runtime/ArrayConstructor.cpp: - (JSC::constructArrayWithSizeQuirk): - * runtime/ArrayConstructor.h: - (JSC): - * runtime/ArrayPrototype.cpp: - (JSC::arrayProtoFuncConcat): - (JSC::arrayProtoFuncSlice): - (JSC::arrayProtoFuncSplice): - (JSC::arrayProtoFuncFilter): - (JSC::arrayProtoFuncMap): - * runtime/Butterfly.h: - (JSC::Butterfly::contiguousInt32): - (JSC::Butterfly::contiguousDouble): - (JSC::Butterfly::fromContiguous): - * runtime/ButterflyInlineMethods.h: - (JSC::Butterfly::createUninitializedDuringCollection): - * runtime/FunctionPrototype.cpp: - (JSC::functionProtoFuncBind): - * runtime/IndexingHeaderInlineMethods.h: - (JSC::IndexingHeader::indexingPayloadSizeInBytes): - * runtime/IndexingType.cpp: - (JSC::leastUpperBoundOfIndexingTypes): - (JSC): - (JSC::leastUpperBoundOfIndexingTypeAndType): - (JSC::leastUpperBoundOfIndexingTypeAndValue): - (JSC::indexingTypeToString): - * runtime/IndexingType.h: - (JSC): - (JSC::hasUndecided): - (JSC::hasInt32): - (JSC::hasDouble): - * runtime/JSArray.cpp: - (JSC::JSArray::setLength): - (JSC::JSArray::pop): - (JSC::JSArray::push): - (JSC::JSArray::shiftCountWithAnyIndexingType): - (JSC::JSArray::unshiftCountWithAnyIndexingType): - (JSC::compareNumbersForQSortWithInt32): - (JSC): - (JSC::compareNumbersForQSortWithDouble): - (JSC::JSArray::sortNumericVector): - (JSC::JSArray::sortNumeric): - (JSC::JSArray::sortCompactedVector): - (JSC::JSArray::sort): - (JSC::JSArray::sortVector): - (JSC::JSArray::fillArgList): - (JSC::JSArray::copyToArguments): - (JSC::JSArray::compactForSorting): - * runtime/JSArray.h: - (JSArray): - (JSC::createContiguousArrayButterfly): - (JSC::JSArray::create): - (JSC::JSArray::tryCreateUninitialized): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::reset): - (JSC): - (JSC::JSGlobalObject::haveABadTime): - (JSC::JSGlobalObject::visitChildren): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::originalArrayStructureForIndexingType): - (JSC::JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation): - (JSC::JSGlobalObject::arrayStructureForProfileDuringAllocation): - (JSC::JSGlobalObject::isOriginalArrayStructure): - (JSC::constructEmptyArray): - (JSC::constructArray): - * runtime/JSObject.cpp: - (JSC::JSObject::copyButterfly): - (JSC::JSObject::getOwnPropertySlotByIndex): - (JSC::JSObject::putByIndex): - (JSC::JSObject::enterDictionaryIndexingMode): - (JSC::JSObject::createInitialIndexedStorage): - (JSC): - (JSC::JSObject::createInitialUndecided): - (JSC::JSObject::createInitialInt32): - (JSC::JSObject::createInitialDouble): - (JSC::JSObject::createInitialContiguous): - (JSC::JSObject::convertUndecidedToInt32): - (JSC::JSObject::convertUndecidedToDouble): - (JSC::JSObject::convertUndecidedToContiguous): - (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements): - (JSC::JSObject::convertUndecidedToArrayStorage): - (JSC::JSObject::convertInt32ToDouble): - (JSC::JSObject::convertInt32ToContiguous): - (JSC::JSObject::convertInt32ToArrayStorage): - (JSC::JSObject::convertDoubleToContiguous): - (JSC::JSObject::convertDoubleToArrayStorage): - (JSC::JSObject::convertContiguousToArrayStorage): - (JSC::JSObject::convertUndecidedForValue): - (JSC::JSObject::convertInt32ForValue): - (JSC::JSObject::setIndexQuicklyToUndecided): - (JSC::JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex): - (JSC::JSObject::convertDoubleToContiguousWhilePerformingSetIndex): - (JSC::JSObject::ensureInt32Slow): - (JSC::JSObject::ensureDoubleSlow): - (JSC::JSObject::ensureContiguousSlow): - (JSC::JSObject::ensureArrayStorageSlow): - (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): - (JSC::JSObject::switchToSlowPutArrayStorage): - (JSC::JSObject::deletePropertyByIndex): - (JSC::JSObject::getOwnPropertyNames): - (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes): - (JSC::JSObject::putByIndexBeyondVectorLength): - (JSC::JSObject::putDirectIndexBeyondVectorLength): - (JSC::JSObject::getNewVectorLength): - (JSC::JSObject::countElements): - (JSC::JSObject::ensureLengthSlow): - (JSC::JSObject::getOwnPropertyDescriptor): - * runtime/JSObject.h: - (JSC::JSObject::getArrayLength): - (JSC::JSObject::getVectorLength): - (JSC::JSObject::canGetIndexQuickly): - (JSC::JSObject::getIndexQuickly): - (JSC::JSObject::tryGetIndexQuickly): - (JSC::JSObject::canSetIndexQuickly): - (JSC::JSObject::canSetIndexQuicklyForPutDirect): - (JSC::JSObject::setIndexQuickly): - (JSC::JSObject::initializeIndex): - (JSC::JSObject::hasSparseMap): - (JSC::JSObject::inSparseIndexingMode): - (JSObject): - (JSC::JSObject::ensureInt32): - (JSC::JSObject::ensureDouble): - (JSC::JSObject::ensureLength): - (JSC::JSObject::indexingData): - (JSC::JSObject::currentIndexingData): - (JSC::JSObject::getHolyIndexQuickly): - (JSC::JSObject::relevantLength): - (JSC::JSObject::currentRelevantLength): - * runtime/JSValue.cpp: - (JSC::JSValue::description): - * runtime/LiteralParser.cpp: - (JSC::::parse): - * runtime/ObjectConstructor.cpp: - (JSC::objectConstructorGetOwnPropertyNames): - (JSC::objectConstructorKeys): - * runtime/StringPrototype.cpp: - (JSC::stringProtoFuncMatch): - (JSC::stringProtoFuncSplit): - * runtime/Structure.cpp: - (JSC::Structure::nonPropertyTransition): - * runtime/StructureTransitionTable.h: - (JSC::newIndexingType): - 2012-11-08 Balazs Kilvady <kilvadyb@homejinni.com> ASSERT problem on MIPS diff --git a/Source/JavaScriptCore/DerivedSources.pri b/Source/JavaScriptCore/DerivedSources.pri index f9bbbf67c..03a935575 100644 --- a/Source/JavaScriptCore/DerivedSources.pri +++ b/Source/JavaScriptCore/DerivedSources.pri @@ -102,7 +102,7 @@ for(dir, DIRS) { exists($$file): LLINT_FILES += $$file } -if(linux-*|win32) { +if(linux-*|win32):!equals(QT_ARCH, "arm") { #GENERATOR: LLInt llint.output = ${QMAKE_FILE_IN_PATH}$${QMAKE_DIR_SEP}LLIntAssembly.h llint.script = $$PWD/offlineasm/asm.rb diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am index 6c7eac9e3..d68a22b9f 100644 --- a/Source/JavaScriptCore/GNUmakefile.list.am +++ b/Source/JavaScriptCore/GNUmakefile.list.am @@ -83,8 +83,6 @@ javascriptcore_sources += \ Source/JavaScriptCore/assembler/RepatchBuffer.h \ Source/JavaScriptCore/assembler/SH4Assembler.h \ Source/JavaScriptCore/assembler/X86Assembler.h \ - Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp \ - Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h \ Source/JavaScriptCore/bytecode/ArrayProfile.cpp \ Source/JavaScriptCore/bytecode/ArrayProfile.h \ Source/JavaScriptCore/bytecode/ByValInfo.h \ @@ -256,9 +254,9 @@ javascriptcore_sources += \ Source/JavaScriptCore/heap/CopiedBlock.h \ Source/JavaScriptCore/heap/CopiedSpace.cpp \ Source/JavaScriptCore/heap/CopiedSpace.h \ - Source/JavaScriptCore/heap/CopiedSpaceInlines.h \ + Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h \ Source/JavaScriptCore/heap/CopyVisitor.h \ - Source/JavaScriptCore/heap/CopyVisitorInlines.h \ + Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h \ Source/JavaScriptCore/heap/CopyVisitor.cpp \ Source/JavaScriptCore/heap/CardSet.h \ Source/JavaScriptCore/heap/ConservativeRoots.cpp \ @@ -276,7 +274,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/heap/IncrementalSweeper.cpp \ Source/JavaScriptCore/heap/SlotVisitor.cpp \ Source/JavaScriptCore/heap/SlotVisitor.h \ - Source/JavaScriptCore/heap/SlotVisitorInlines.h \ + Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h \ Source/JavaScriptCore/heap/HandleStack.cpp \ Source/JavaScriptCore/heap/HandleStack.h \ Source/JavaScriptCore/heap/HandleTypes.h \ @@ -299,7 +297,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/heap/MachineStackMarker.h \ Source/JavaScriptCore/heap/MarkStack.cpp \ Source/JavaScriptCore/heap/MarkStack.h \ - Source/JavaScriptCore/heap/MarkStackInlines.h \ + Source/JavaScriptCore/heap/MarkStackInlineMethods.h \ Source/JavaScriptCore/heap/HeapRootVisitor.h \ Source/JavaScriptCore/heap/MarkedAllocator.cpp \ Source/JavaScriptCore/heap/MarkedAllocator.h \ @@ -400,7 +398,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/jit/JIT.h \ Source/JavaScriptCore/jit/JITExceptions.cpp \ Source/JavaScriptCore/jit/JITExceptions.h \ - Source/JavaScriptCore/jit/JITInlines.h \ + Source/JavaScriptCore/jit/JITInlineMethods.h \ Source/JavaScriptCore/jit/JITOpcodes32_64.cpp \ Source/JavaScriptCore/jit/JITOpcodes.cpp \ Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp \ @@ -483,7 +481,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/BooleanObject.h \ Source/JavaScriptCore/runtime/BooleanPrototype.cpp \ Source/JavaScriptCore/runtime/BooleanPrototype.h \ - Source/JavaScriptCore/runtime/ButterflyInlines.h \ + Source/JavaScriptCore/runtime/ButterflyInlineMethods.h \ Source/JavaScriptCore/runtime/Butterfly.h \ Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h \ Source/JavaScriptCore/runtime/CallData.cpp \ @@ -531,7 +529,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/GetterSetter.h \ Source/JavaScriptCore/runtime/Identifier.cpp \ Source/JavaScriptCore/runtime/Identifier.h \ - Source/JavaScriptCore/runtime/IndexingHeaderInlines.h \ + Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h \ Source/JavaScriptCore/runtime/IndexingHeader.h \ Source/JavaScriptCore/runtime/IndexingType.cpp \ Source/JavaScriptCore/runtime/IndexingType.h \ @@ -592,7 +590,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/JSTypeInfo.h \ Source/JavaScriptCore/runtime/JSValue.cpp \ Source/JavaScriptCore/runtime/JSValue.h \ - Source/JavaScriptCore/runtime/JSValueInlines.h \ + Source/JavaScriptCore/runtime/JSValueInlineMethods.h \ Source/JavaScriptCore/runtime/JSVariableObject.cpp \ Source/JavaScriptCore/runtime/JSVariableObject.h \ Source/JavaScriptCore/runtime/JSWithScope.h \ diff --git a/Source/JavaScriptCore/JavaScriptCore.pro b/Source/JavaScriptCore/JavaScriptCore.pro index 924261d4f..c86ca8e3d 100644 --- a/Source/JavaScriptCore/JavaScriptCore.pro +++ b/Source/JavaScriptCore/JavaScriptCore.pro @@ -7,7 +7,7 @@ TEMPLATE = subdirs CONFIG += ordered -if(linux-*|win32*) { +if(linux-*|win32*):!equals(QT_ARCH, "arm") { LLIntOffsetsExtractor.file = LLIntOffsetsExtractor.pro LLIntOffsetsExtractor.makefile = Makefile.LLIntOffsetsExtractor SUBDIRS += LLIntOffsetsExtractor @@ -18,7 +18,7 @@ target.file = Target.pri SUBDIRS += derived_sources target -if(linux-*|win32*):addStrictSubdirOrderBetween(LLIntOffsetsExtractor, derived_sources) +if(linux-*|win32*):!equals(QT_ARCH, "arm"):addStrictSubdirOrderBetween(LLIntOffsetsExtractor, derived_sources) addStrictSubdirOrderBetween(derived_sources, target) jsc.file = jsc.pro diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index e57335015..b23100547 100755 --- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -54,7 +54,6 @@ EXPORTS ?absoluteTimeToWaitTimeoutInterval@WTF@@YAKN@Z ?activityCallback@Heap@JSC@@QAEPAVGCActivityCallback@2@XZ ?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z - ?addFromLiteralData@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBDI@Z ?add@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z ?add@Identifier@JSC@@SA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PBD@Z ?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WTF@@@Z @@ -111,12 +110,11 @@ EXPORTS ?computeHash@SHA1@WTF@@QAEXAAV?$Vector@E$0BE@@2@@Z ?configurable@PropertyDescriptor@JSC@@QBE_NXZ ?construct@JSC@@YAPAVJSObject@1@PAVExecState@1@VJSValue@1@W4ConstructType@1@ABTConstructData@1@ABVArgList@1@@Z + ?constructArray@JSC@@YAPAVJSArray@1@PAVExecState@1@ABVArgList@1@@Z ?constructEmptyObject@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z ?constructFunctionSkippingEvalEnabledCheck@JSC@@YAPAVJSObject@1@PAVExecState@1@PAVJSGlobalObject@1@ABVArgList@1@ABVIdentifier@1@ABVString@WTF@@ABVTextPosition@8@@Z ?constructNumber@JSC@@YAPAVNumberObject@1@PAVExecState@1@PAVJSGlobalObject@1@VJSValue@1@@Z ?constructString@JSC@@YAPAVStringObject@1@PAVExecState@1@PAVJSGlobalObject@1@VJSValue@1@@Z - ?convertDoubleToContiguousWhilePerformingSetIndex@JSObject@JSC@@AAEXAAVJSGlobalData@2@IVJSValue@2@@Z - ?convertInt32ToDoubleOrContiguousWhilePerformingSetIndex@JSObject@JSC@@AAEXAAVJSGlobalData@2@IVJSValue@2@@Z ?convertLatin1ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBEPBEPAPADPAD@Z ?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z ?convertUTF8ToUTF16@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBDPBDPAPA_WPA_WPA_N_N@Z @@ -335,7 +333,6 @@ EXPORTS ?setGarbageCollectionTimerEnabled@Heap@JSC@@QAEX_N@Z ?setGetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z ?setGlobalThis@JSGlobalObject@JSC@@IAEXAAVJSGlobalData@2@PAVJSObject@2@@Z - ?setIndexQuicklyToUndecided@JSObject@JSC@@AAEXAAVJSGlobalData@2@IVJSValue@2@@Z ?setLoc@StatementNode@JSC@@QAEXHH@Z ?setMainThreadCallbacksPaused@WTF@@YAX_N@Z ?setOption@Options@JSC@@SA_NPBD@Z @@ -405,7 +402,6 @@ EXPORTS ?unlock@Mutex@WTF@@QAEXXZ ?unlockAtomicallyInitializedStaticMutex@WTF@@YAXXZ ?unprotect@Heap@JSC@@QAE_NVJSValue@2@@Z - ?updateIndexingType@ArrayAllocationProfile@JSC@@QAEXXZ ?validate@SlotVisitor@JSC@@CAXPAVJSCell@2@@Z ?visitChildren@JSGlobalObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z ?visitChildren@JSObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj index 0e732d187..b1567e2cd 100644 --- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj @@ -538,7 +538,7 @@ >
</File>
<File
- RelativePath="..\..\runtime\ButterflyInlines.h"
+ RelativePath="..\..\runtime\ButterflyInlineMethods.h"
>
</File>
<File
@@ -546,7 +546,7 @@ >
</File>
<File
- RelativePath="..\..\runtime\IndexingHeaderInlines.h"
+ RelativePath="..\..\runtime\IndexingHeaderInlineMethods.h"
>
</File>
<File
@@ -1010,7 +1010,7 @@ >
</File>
<File
- RelativePath="..\..\runtime\JSValueInlines.h"
+ RelativePath="..\..\runtime\JSValueInlineMethods.h"
>
</File>
<File
@@ -1582,14 +1582,6 @@ Name="bytecode"
>
<File
- RelativePath="..\..\bytecode\ArrayAllocationProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ArrayAllocationProfile.h"
- >
- </File>
- <File
RelativePath="..\..\bytecode\ArrayProfile.cpp"
>
</File>
@@ -1986,7 +1978,7 @@ >
</File>
<File
- RelativePath="..\..\jit\JITInlines.h"
+ RelativePath="..\..\jit\JITInlineMethods.h"
>
</File>
<File
@@ -2362,7 +2354,7 @@ >
</File>
<File
- RelativePath="..\..\heap\CopiedSpaceInlines.h"
+ RelativePath="..\..\heap\CopiedSpaceInlineMethods.h"
>
</File>
<File
@@ -2374,7 +2366,7 @@ >
</File>
<File
- RelativePath="..\..\heap\CopyVisitorInlines.h"
+ RelativePath="..\..\heap\CopyVisitorInlineMethods.h"
>
</File>
<File
@@ -2562,7 +2554,7 @@ >
</File>
<File
- RelativePath="..\..\heap\MarkStackInlines.h"
+ RelativePath="..\..\heap\MarkStackInlineMethods.h"
>
</File>
<File
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index 87747ca6d..3cada1cd7 100644 --- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -165,9 +165,6 @@ 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8023E91613832300A0BA45 /* ByValInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */; }; - 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */; }; 0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */; }; @@ -196,9 +193,9 @@ 0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FB7F39615ED8E4600F167B2 /* ArrayStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0FB7F39815ED8E4600F167B2 /* ButterflyInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38C15ED8E3800F167B2 /* ButterflyInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38D15ED8E3800F167B2 /* IndexingHeader.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39115ED8E3800F167B2 /* Reject.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -453,7 +450,7 @@ 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */; }; 8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86F75EFB151C062F007C9BA3 /* RegExpCachedResult.cpp */; }; 8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86F75EFD151C062F007C9BA3 /* RegExpMatchesArray.cpp */; }; - 865A30F1135007E100CDB49E /* JSValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSValueInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 865A30F1135007E100CDB49E /* JSValueInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSValueInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; 865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; settings = {ATTRIBUTES = (Private, ); }; }; 866739D213BFDE710023D87C /* BigInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D013BFDE710023D87C /* BigInteger.h */; }; 866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */ = {isa = PBXBuildFile; fileRef = 866739D113BFDE710023D87C /* Uint16WithFraction.h */; }; @@ -489,7 +486,7 @@ 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; }; 86CAFEE31035DDE60028A609 /* Executable.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CAFEE21035DDE60028A609 /* Executable.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 86CC85A10EE79A4700288682 /* JITInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CC85A00EE79A4700288682 /* JITInlines.h */; }; + 86CC85A10EE79A4700288682 /* JITInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CC85A00EE79A4700288682 /* JITInlineMethods.h */; }; 86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85A20EE79B7400288682 /* JITCall.cpp */; }; 86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */; }; 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CCEFDD0F413F8900FD7F9E /* JITCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -714,11 +711,11 @@ BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; }; C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; }; C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122E015DD9AB300790E3A /* MarkStackInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; - C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C21122E315DD9AB300790E3A /* MarkStackInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2160FE715F7E95E00942DFC /* SlotVisitorInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCB408515C0A3C30048932B /* SlotVisitorInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */; }; C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1316262BDD005AC5FD /* CopyVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; }; - C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2239D1916262BDD005AC5FD /* CopyVisitorInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1416262BDD005AC5FD /* CopyVisitorInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2239D1516262BDD005AC5FD /* GCThread.cpp */; }; C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1616262BDD005AC5FD /* GCThread.h */; }; C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C225494215F7DBAA0065E898 /* SlotVisitor.cpp */; }; @@ -731,7 +728,7 @@ C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A7F687160432D400F76B98 /* JSDestructibleObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */; }; - C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */; }; @@ -954,9 +951,6 @@ 0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; }; 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCCallHelpers.h; path = dfg/DFGCCallHelpers.h; sourceTree = "<group>"; }; 0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = "<group>"; }; - 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; }; - 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayAllocationProfile.cpp; sourceTree = "<group>"; }; - 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; }; 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSymbolTableObject.cpp; sourceTree = "<group>"; }; 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSymbolTableObject.h; sourceTree = "<group>"; }; 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObject.cpp; sourceTree = "<group>"; }; @@ -985,9 +979,9 @@ 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayConventions.h; sourceTree = "<group>"; }; 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayStorage.h; sourceTree = "<group>"; }; 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Butterfly.h; sourceTree = "<group>"; }; - 0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ButterflyInlines.h; sourceTree = "<group>"; }; + 0FB7F38C15ED8E3800F167B2 /* ButterflyInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ButterflyInlineMethods.h; sourceTree = "<group>"; }; 0FB7F38D15ED8E3800F167B2 /* IndexingHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexingHeader.h; sourceTree = "<group>"; }; - 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexingHeaderInlines.h; sourceTree = "<group>"; }; + 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexingHeaderInlineMethods.h; sourceTree = "<group>"; }; 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexingType.h; sourceTree = "<group>"; }; 0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyStorage.h; sourceTree = "<group>"; }; 0FB7F39115ED8E3800F167B2 /* Reject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reject.h; sourceTree = "<group>"; }; @@ -1012,7 +1006,7 @@ 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; }; 0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; }; 0FC815141405118D00CFA603 /* VTableSpectrum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTableSpectrum.h; sourceTree = "<group>"; }; - 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitorInlines.h; sourceTree = "<group>"; }; + 0FCB408515C0A3C30048932B /* SlotVisitorInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitorInlineMethods.h; sourceTree = "<group>"; }; 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDriver.cpp; path = dfg/DFGDriver.cpp; sourceTree = "<group>"; }; 0FD3C82214115D0E00FD81CB /* DFGDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDriver.h; path = dfg/DFGDriver.h; sourceTree = "<group>"; }; 0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDominators.cpp; path = dfg/DFGDominators.cpp; sourceTree = "<group>"; }; @@ -1232,7 +1226,7 @@ 863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrCanonicalizeUCS2.cpp; path = yarr/YarrCanonicalizeUCS2.cpp; sourceTree = "<group>"; }; 863C6D991521111200585E4E /* YarrCanonicalizeUCS2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrCanonicalizeUCS2.h; path = yarr/YarrCanonicalizeUCS2.h; sourceTree = "<group>"; }; 863C6D9A1521111200585E4E /* YarrCanonicalizeUCS2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = YarrCanonicalizeUCS2.js; path = yarr/YarrCanonicalizeUCS2.js; sourceTree = "<group>"; }; - 865A30F0135007E100CDB49E /* JSValueInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueInlines.h; sourceTree = "<group>"; }; + 865A30F0135007E100CDB49E /* JSValueInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueInlineMethods.h; sourceTree = "<group>"; }; 865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; }; 866739D013BFDE710023D87C /* BigInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BigInteger.h; sourceTree = "<group>"; }; 866739D113BFDE710023D87C /* Uint16WithFraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uint16WithFraction.h; sourceTree = "<group>"; }; @@ -1274,7 +1268,7 @@ 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIPSAssembler.h; sourceTree = "<group>"; }; 86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; }; 86CAFEE21035DDE60028A609 /* Executable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Executable.h; sourceTree = "<group>"; }; - 86CC85A00EE79A4700288682 /* JITInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlines.h; sourceTree = "<group>"; }; + 86CC85A00EE79A4700288682 /* JITInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineMethods.h; sourceTree = "<group>"; }; 86CC85A20EE79B7400288682 /* JITCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCall.cpp; sourceTree = "<group>"; }; 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess.cpp; sourceTree = "<group>"; }; 86CCEFDD0F413F8900FD7F9E /* JITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCode.h; sourceTree = "<group>"; }; @@ -1507,10 +1501,10 @@ BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; }; C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; }; C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; }; - C21122E015DD9AB300790E3A /* MarkStackInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStackInlines.h; sourceTree = "<group>"; }; + C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStackInlineMethods.h; sourceTree = "<group>"; }; C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopyVisitor.cpp; sourceTree = "<group>"; }; C2239D1316262BDD005AC5FD /* CopyVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitor.h; sourceTree = "<group>"; }; - C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitorInlines.h; sourceTree = "<group>"; }; + C2239D1416262BDD005AC5FD /* CopyVisitorInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitorInlineMethods.h; sourceTree = "<group>"; }; C2239D1516262BDD005AC5FD /* GCThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThread.cpp; sourceTree = "<group>"; }; C2239D1616262BDD005AC5FD /* GCThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThread.h; sourceTree = "<group>"; }; C225494215F7DBAA0065E898 /* SlotVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotVisitor.cpp; sourceTree = "<group>"; }; @@ -1522,7 +1516,7 @@ C2A7F687160432D400F76B98 /* JSDestructibleObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObject.h; sourceTree = "<group>"; }; C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocator.h; sourceTree = "<group>"; }; C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedAllocator.cpp; sourceTree = "<group>"; }; - C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpaceInlines.h; sourceTree = "<group>"; }; + C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpaceInlineMethods.h; sourceTree = "<group>"; }; C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedBlock.h; sourceTree = "<group>"; }; C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapBlock.h; sourceTree = "<group>"; }; C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCActivityCallback.cpp; sourceTree = "<group>"; }; @@ -1822,7 +1816,7 @@ 0F21C26614BE5F5E00ADC64B /* JITDriver.h */, 0F46807F14BA572700BFE272 /* JITExceptions.cpp */, 0F46808014BA572700BFE272 /* JITExceptions.h */, - 86CC85A00EE79A4700288682 /* JITInlines.h */, + 86CC85A00EE79A4700288682 /* JITInlineMethods.h */, BCDD51E90FB8DF74004A8BDC /* JITOpcodes.cpp */, A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */, 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */, @@ -1848,7 +1842,7 @@ children = ( C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */, C2239D1316262BDD005AC5FD /* CopyVisitor.h */, - C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */, + C2239D1416262BDD005AC5FD /* CopyVisitorInlineMethods.h */, C2239D1516262BDD005AC5FD /* GCThread.cpp */, C2239D1616262BDD005AC5FD /* GCThread.h */, C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */, @@ -1856,7 +1850,7 @@ C225494215F7DBAA0065E898 /* SlotVisitor.cpp */, C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */, C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */, - C21122E015DD9AB300790E3A /* MarkStackInlines.h */, + C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */, C2E526BB1590EF000054E48D /* HeapTimer.cpp */, C2E526BC1590EF000054E48D /* HeapTimer.h */, C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */, @@ -1870,7 +1864,7 @@ C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */, C240305314B404C90079EB64 /* CopiedSpace.cpp */, C2EAA3F8149A830800FCE112 /* CopiedSpace.h */, - C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */, + C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlineMethods.h */, 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */, 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */, BCBE2CAD14E985AA000593AD /* GCAssertions.h */, @@ -1902,7 +1896,7 @@ 142D6F0F13539A4100B02E86 /* MarkStack.h */, 1497209014EB831500FEB1B7 /* PassWeak.h */, 14BA78F013AAB88F005B7C2C /* SlotVisitor.h */, - 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */, + 0FCB408515C0A3C30048932B /* SlotVisitorInlineMethods.h */, 142E3132134FF0A600AFADB5 /* Strong.h */, 145722851437E140005FDE26 /* StrongInlines.h */, 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */, @@ -2106,7 +2100,7 @@ BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */, BC7952350E15EB5600A898AB /* BooleanPrototype.h */, 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */, - 0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */, + 0FB7F38C15ED8E3800F167B2 /* ButterflyInlineMethods.h */, 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */, BCA62DFE0E2826230004F30D /* CallData.cpp */, 145C507F0D9DF63B0088F6B9 /* CallData.h */, @@ -2152,7 +2146,7 @@ 933A349D038AE80F008635CE /* Identifier.cpp */, 933A349A038AE7C6008635CE /* Identifier.h */, 0FB7F38D15ED8E3800F167B2 /* IndexingHeader.h */, - 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlines.h */, + 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlineMethods.h */, 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */, 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */, E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */, @@ -2209,7 +2203,7 @@ 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */, F692A8870255597D01FF60F7 /* JSValue.cpp */, 14ABB36E099C076400E2A24F /* JSValue.h */, - 865A30F0135007E100CDB49E /* JSValueInlines.h */, + 865A30F0135007E100CDB49E /* JSValueInlineMethods.h */, BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */, 14F252560D08DD8D004ECFFF /* JSVariableObject.h */, 1442565F15EDE98D0066A49B /* JSWithScope.cpp */, @@ -2368,7 +2362,6 @@ 0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */, 0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */, 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */, - 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */, 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */, 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */, 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */, @@ -2522,8 +2515,6 @@ 969A078F0ED1D3AE00F1F681 /* bytecode */ = { isa = PBXGroup; children = ( - 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */, - 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */, 0F63945115D07051006A597C /* ArrayProfile.cpp */, 0F63945215D07051006A597C /* ArrayProfile.h */, 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */, @@ -2625,14 +2616,14 @@ C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */, FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */, C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */, - C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */, + C2239D1916262BDD005AC5FD /* CopyVisitorInlineMethods.h in Headers */, C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */, C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */, FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */, C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */, - C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */, + C2160FE715F7E95E00942DFC /* SlotVisitorInlineMethods.h in Headers */, C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */, - C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */, + C21122E315DD9AB300790E3A /* MarkStackInlineMethods.h in Headers */, C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */, BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */, BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */, @@ -2645,7 +2636,7 @@ BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */, C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */, C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */, - C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */, + C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlineMethods.h in Headers */, 969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */, 869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */, BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */, @@ -2727,7 +2718,7 @@ BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */, 1429D9300ED22D7000B89619 /* JIT.h in Headers */, 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */, - 86CC85A10EE79A4700288682 /* JITInlines.h in Headers */, + 86CC85A10EE79A4700288682 /* JITInlineMethods.h in Headers */, 960626960FB8EC02009798AB /* JITStubCall.h in Headers */, 14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */, A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */, @@ -2769,7 +2760,7 @@ BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */, 6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */, BC18C42B0E16F5CD00B34460 /* JSValue.h in Headers */, - 865A30F1135007E100CDB49E /* JSValueInlines.h in Headers */, + 865A30F1135007E100CDB49E /* JSValueInlineMethods.h in Headers */, BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */, BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */, A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */, @@ -3003,9 +2994,9 @@ 0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */, 0FB7F39615ED8E4600F167B2 /* ArrayStorage.h in Headers */, 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */, - 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */, + 0FB7F39815ED8E4600F167B2 /* ButterflyInlineMethods.h in Headers */, 0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */, - 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */, + 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlineMethods.h in Headers */, 0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */, 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */, 0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */, @@ -3017,8 +3008,6 @@ 0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */, 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */, C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */, - 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */, - 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */, A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */, A77F1822164088B200640A47 /* CodeCache.h in Headers */, A77F1825164192C700640A47 /* ParserModes.h in Headers */, @@ -3598,7 +3587,6 @@ C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */, C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */, C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */, - 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */, A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */, A77F1821164088B200640A47 /* CodeCache.cpp in Sources */, ); diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri index f978fb46b..b0fcc16e7 100644 --- a/Source/JavaScriptCore/Target.pri +++ b/Source/JavaScriptCore/Target.pri @@ -50,7 +50,6 @@ SOURCES += \ assembler/MacroAssembler.cpp \ assembler/MacroAssemblerARM.cpp \ assembler/MacroAssemblerSH4.cpp \ - bytecode/ArrayAllocationProfile.cpp \ bytecode/ArrayProfile.cpp \ bytecode/CallLinkInfo.cpp \ bytecode/CallLinkStatus.cpp \ diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h index 673031b7a..c75adb7e9 100644 --- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -586,13 +586,6 @@ public: public: typedef Vector<Jump, 16> JumpVector; - - JumpList() { } - - JumpList(Jump jump) - { - append(jump); - } void link(AbstractMacroAssembler<AssemblerType>* masm) { diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h index 53cb80c21..66db26acb 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h @@ -826,15 +826,11 @@ public: m_assembler.ucomisd_rr(right, left); if (cond == DoubleEqual) { - if (left == right) - return Jump(m_assembler.jnp()); Jump isUnordered(m_assembler.jp()); Jump result = Jump(m_assembler.je()); isUnordered.link(this); return result; } else if (cond == DoubleNotEqualOrUnordered) { - if (left == right) - return Jump(m_assembler.jp()); Jump isUnordered(m_assembler.jp()); Jump isEqual(m_assembler.je()); isUnordered.link(this); diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h index 4d08b70ce..ecb178e88 100644 --- a/Source/JavaScriptCore/assembler/X86Assembler.h +++ b/Source/JavaScriptCore/assembler/X86Assembler.h @@ -1475,12 +1475,6 @@ public: return m_formatter.immediateRel32(); } - AssemblerLabel jnp() - { - m_formatter.twoByteOp(jccRel32(ConditionNP)); - return m_formatter.immediateRel32(); - } - AssemblerLabel jp() { m_formatter.twoByteOp(jccRel32(ConditionP)); @@ -2320,9 +2314,6 @@ private: // Format a REX prefix byte. inline void emitRex(bool w, int r, int x, int b) { - ASSERT(r >= 0); - ASSERT(x >= 0); - ASSERT(b >= 0); m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3)); } diff --git a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp deleted file mode 100644 index aa682da86..000000000 --- a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ArrayAllocationProfile.h" - -namespace JSC { - -void ArrayAllocationProfile::updateIndexingType() -{ - if (!m_lastArray) - return; - m_currentIndexingType = leastUpperBoundOfIndexingTypes(m_currentIndexingType, m_lastArray->structure()->indexingType()); - m_lastArray = 0; -} - -} // namespace JSC - diff --git a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h deleted file mode 100644 index a1647fad4..000000000 --- a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArrayAllocationProfile_h -#define ArrayAllocationProfile_h - -#include "IndexingType.h" -#include "JSArray.h" - -namespace JSC { - -class ArrayAllocationProfile { -public: - ArrayAllocationProfile() - : m_currentIndexingType(ArrayWithUndecided) - , m_lastArray(0) - { - } - - IndexingType selectIndexingType() - { - if (m_lastArray && UNLIKELY(m_lastArray->structure()->indexingType() != m_currentIndexingType)) - updateIndexingType(); - return m_currentIndexingType; - } - - JSArray* updateLastAllocation(JSArray* lastArray) - { - m_lastArray = lastArray; - return lastArray; - } - - JS_EXPORT_PRIVATE void updateIndexingType(); - - static IndexingType selectIndexingTypeFor(ArrayAllocationProfile* profile) - { - if (!profile) - return ArrayWithUndecided; - return profile->selectIndexingType(); - } - - static JSArray* updateLastAllocationFor(ArrayAllocationProfile* profile, JSArray* lastArray) - { - if (profile) - profile->updateLastAllocation(lastArray); - return lastArray; - } - -private: - - IndexingType m_currentIndexingType; - JSArray* m_lastArray; -}; - -} // namespace JSC - -#endif // ArrayAllocationProfile_h - diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp index 51baf332f..5a87380fd 100644 --- a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp +++ b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp @@ -65,13 +65,6 @@ const char* arrayModesToString(ArrayModes arrayModes) return result; } -ArrayModes ArrayProfile::updatedObservedArrayModes() const -{ - if (m_lastSeenStructure) - return m_observedArrayModes | arrayModeFromStructure(m_lastSeenStructure); - return m_observedArrayModes; -} - void ArrayProfile::computeUpdatedPrediction(CodeBlock* codeBlock, OperationInProgress operation) { if (m_lastSeenStructure) { diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.h b/Source/JavaScriptCore/bytecode/ArrayProfile.h index 5116cd36f..376684fc1 100644 --- a/Source/JavaScriptCore/bytecode/ArrayProfile.h +++ b/Source/JavaScriptCore/bytecode/ArrayProfile.h @@ -45,20 +45,15 @@ typedef unsigned ArrayModes; #define ALL_NON_ARRAY_ARRAY_MODES \ (asArrayModes(NonArray) \ - | asArrayModes(NonArrayWithInt32) \ - | asArrayModes(NonArrayWithDouble) \ - | asArrayModes(NonArrayWithContiguous) \ - | asArrayModes(NonArrayWithArrayStorage) \ - | asArrayModes(NonArrayWithSlowPutArrayStorage)) + | asArrayModes(NonArrayWithContiguous) \ + | asArrayModes(NonArrayWithArrayStorage) \ + | asArrayModes(NonArrayWithSlowPutArrayStorage)) #define ALL_ARRAY_ARRAY_MODES \ (asArrayModes(ArrayClass) \ - | asArrayModes(ArrayWithUndecided) \ - | asArrayModes(ArrayWithInt32) \ - | asArrayModes(ArrayWithDouble) \ - | asArrayModes(ArrayWithContiguous) \ - | asArrayModes(ArrayWithArrayStorage) \ - | asArrayModes(ArrayWithSlowPutArrayStorage)) + | asArrayModes(ArrayWithContiguous) \ + | asArrayModes(ArrayWithArrayStorage) \ + | asArrayModes(ArrayWithSlowPutArrayStorage)) #define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES) @@ -84,36 +79,6 @@ inline bool arrayModesAlreadyChecked(ArrayModes proven, ArrayModes expected) return (expected | proven) == expected; } -inline bool arrayModesInclude(ArrayModes arrayModes, IndexingType shape) -{ - return !!(arrayModes & (asArrayModes(NonArray | shape) | asArrayModes(ArrayClass | shape))); -} - -inline bool shouldUseSlowPutArrayStorage(ArrayModes arrayModes) -{ - return arrayModesInclude(arrayModes, SlowPutArrayStorageShape); -} - -inline bool shouldUseFastArrayStorage(ArrayModes arrayModes) -{ - return arrayModesInclude(arrayModes, ArrayStorageShape); -} - -inline bool shouldUseContiguous(ArrayModes arrayModes) -{ - return arrayModesInclude(arrayModes, ContiguousShape); -} - -inline bool shouldUseDouble(ArrayModes arrayModes) -{ - return arrayModesInclude(arrayModes, DoubleShape); -} - -inline bool shouldUseInt32(ArrayModes arrayModes) -{ - return arrayModesInclude(arrayModes, Int32Shape); -} - class ArrayProfile { public: ArrayProfile() @@ -163,7 +128,6 @@ public: return !structureIsPolymorphic() && m_expectedStructure; } ArrayModes observedArrayModes() const { return m_observedArrayModes; } - ArrayModes updatedObservedArrayModes() const; // Computes the observed array modes without updating the profile. bool mayInterceptIndexedAccesses() const { return m_mayInterceptIndexedAccesses; } bool mayStoreToHole() const { return m_mayStoreToHole; } diff --git a/Source/JavaScriptCore/bytecode/ByValInfo.h b/Source/JavaScriptCore/bytecode/ByValInfo.h index 3f79967df..8cba4463d 100644 --- a/Source/JavaScriptCore/bytecode/ByValInfo.h +++ b/Source/JavaScriptCore/bytecode/ByValInfo.h @@ -39,8 +39,6 @@ namespace JSC { enum JITArrayMode { - JITInt32, - JITDouble, JITContiguous, JITArrayStorage, JITInt8Array, @@ -57,8 +55,6 @@ enum JITArrayMode { inline bool isOptimizableIndexingType(IndexingType indexingType) { switch (indexingType) { - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: return true; @@ -81,10 +77,6 @@ inline bool hasOptimizableIndexing(Structure* structure) inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType) { switch (indexingType) { - case ALL_INT32_INDEXING_TYPES: - return JITInt32; - case ALL_DOUBLE_INDEXING_TYPES: - return JITDouble; case ALL_CONTIGUOUS_INDEXING_TYPES: return JITContiguous; case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 83833c6ec..5686d5d2c 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -44,7 +44,7 @@ #include "JSValue.h" #include "LowLevelInterpreter.h" #include "RepatchBuffer.h" -#include "SlotVisitorInlines.h" +#include "SlotVisitorInlineMethods.h" #include <stdio.h> #include <wtf/StringExtras.h> #include <wtf/UnusedParam.h> @@ -654,7 +654,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int argc = (++it)->u.operand; dataLog("[%4d] new_array\t %s, %s, %d", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc); dumpBytecodeCommentAndNewLine(location); - ++it; // Skip array allocation profile. break; } case op_new_array_with_size: { @@ -662,7 +661,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int length = (++it)->u.operand; dataLog("[%4d] new_array_with_size\t %s, %s", location, registerName(exec, dst).data(), registerName(exec, length).data()); dumpBytecodeCommentAndNewLine(location); - ++it; // Skip array allocation profile. break; } case op_new_array_buffer: { @@ -671,7 +669,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int argc = (++it)->u.operand; dataLog("[%4d] new_array_buffer\t %s, %d, %d", location, registerName(exec, dst).data(), argv, argc); dumpBytecodeCommentAndNewLine(location); - ++it; // Skip array allocation profile. break; } case op_new_regexp: { @@ -1749,8 +1746,6 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin #if ENABLE(DFG_JIT) if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles()) m_arrayProfiles.grow(size); - if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles()) - m_arrayAllocationProfiles.grow(size); if (size_t size = unlinkedCodeBlock->numberOfValueProfiles()) m_valueProfiles.grow(size); #endif @@ -1805,32 +1800,22 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin break; } - case op_new_array: - case op_new_array_buffer: - case op_new_array_with_size: { - int arrayAllocationProfileIndex = pc[i + opLength - 1].u.operand; - instructions[i + opLength - 1] = &m_arrayAllocationProfiles[arrayAllocationProfileIndex]; - break; - } -#endif - case op_call: case op_call_eval: { -#if ENABLE(DFG_JIT) int arrayProfileIndex = pc[i + opLength - 1].u.operand; m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex]; -#endif -#if ENABLE(LLINT) - instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand]; -#endif + // fallthrough +#if !ENABLE(LLINT) break; +#endif } - case op_construct: +#endif #if ENABLE(LLINT) + case op_construct: instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand]; -#endif break; +#endif case op_get_by_id_out_of_line: case op_get_by_id_self: case op_get_by_id_proto: @@ -2805,28 +2790,18 @@ void CodeBlock::updateAllPredictionsAndCountLiveness( #if ENABLE(DFG_JIT) m_lazyOperandValueProfiles.computeUpdatedPredictions(operation); #endif -} - -void CodeBlock::updateAllValueProfilePredictions(OperationInProgress operation) -{ - unsigned ignoredValue1, ignoredValue2; - updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2); -} - -void CodeBlock::updateAllArrayPredictions(OperationInProgress operation) -{ + + // Don't count the array profiles towards statistics, since each array profile + // site also has a value profile site - so we already know whether or not it's + // live. for (unsigned i = m_arrayProfiles.size(); i--;) m_arrayProfiles[i].computeUpdatedPrediction(this, operation); - - // Don't count these either, for similar reasons. - for (unsigned i = m_arrayAllocationProfiles.size(); i--;) - m_arrayAllocationProfiles[i].updateIndexingType(); } void CodeBlock::updateAllPredictions(OperationInProgress operation) { - updateAllValueProfilePredictions(operation); - updateAllArrayPredictions(operation); + unsigned ignoredValue1, ignoredValue2; + updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2); } bool CodeBlock::shouldOptimizeNow() @@ -2842,14 +2817,12 @@ bool CodeBlock::shouldOptimizeNow() if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay()) return true; - updateAllArrayPredictions(); - unsigned numberOfLiveNonArgumentValueProfiles; unsigned numberOfSamplesInProfiles; updateAllPredictionsAndCountLiveness(NoOperation, numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles); #if ENABLE(JIT_VERBOSE_OSR) - dataLog("Profile hotness: %lf (%u / %u), %lf (%u / %u)\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), numberOfLiveNonArgumentValueProfiles, numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles(), numberOfSamplesInProfiles, ValueProfile::numberOfBuckets * numberOfValueProfiles()); + dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles()); #endif if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate()) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index 0199935bb..a28064940 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -755,13 +755,6 @@ namespace JSC { } ArrayProfile* getArrayProfile(unsigned bytecodeOffset); ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset); - - unsigned numberOfArrayAllocationProfiles() const { return m_arrayAllocationProfiles.size(); } - ArrayAllocationProfile* addArrayAllocationProfile() - { - m_arrayAllocationProfiles.append(ArrayAllocationProfile()); - return &m_arrayAllocationProfiles.last(); - } #endif // Exception handling support @@ -1152,13 +1145,9 @@ namespace JSC { #if ENABLE(VALUE_PROFILER) bool shouldOptimizeNow(); - void updateAllValueProfilePredictions(OperationInProgress = NoOperation); - void updateAllArrayPredictions(OperationInProgress = NoOperation); void updateAllPredictions(OperationInProgress = NoOperation); #else bool shouldOptimizeNow() { return false; } - void updateAllValueProfilePredictions(OperationInProgress = NoOperation) { } - void updateAllArrayPredictions(OperationInProgress = NoOperation) { } void updateAllPredictions(OperationInProgress = NoOperation) { } #endif @@ -1341,7 +1330,6 @@ namespace JSC { SegmentedVector<ValueProfile, 8> m_valueProfiles; SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles; SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles; - SegmentedVector<ArrayAllocationProfile, 8> m_arrayAllocationProfiles; ArrayProfileVector m_arrayProfiles; unsigned m_executionEntryCount; #endif diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h index 7132adfd4..60d313ad4 100644 --- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h +++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.h @@ -58,8 +58,6 @@ inline const char* exitKindToString(ExitKind kind) return "BadCache"; case BadWeakConstantCache: return "BadWeakConstantCache"; - case BadIndexingType: - return "BadIndexingType"; case Overflow: return "Overflow"; case NegativeZero: diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h index 50b80e03c..9fcf509f6 100644 --- a/Source/JavaScriptCore/bytecode/Instruction.h +++ b/Source/JavaScriptCore/bytecode/Instruction.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,7 +47,6 @@ namespace JSC { // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best // solution for now - will need to something smarter if/when we actually want mixed-mode operation. - class ArrayAllocationProfile; class ArrayProfile; class JSCell; class Structure; @@ -194,7 +193,6 @@ namespace JSC { Instruction(ValueProfile* profile) { u.profile = profile; } Instruction(ArrayProfile* profile) { u.arrayProfile = profile; } - Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; } Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; } @@ -214,7 +212,6 @@ namespace JSC { LLIntCallLinkInfo* callLinkInfo; ValueProfile* profile; ArrayProfile* arrayProfile; - ArrayAllocationProfile* arrayAllocationProfile; void* pointer; bool* predicatePointer; } u; diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h index 38d314d78..8979d0b7b 100644 --- a/Source/JavaScriptCore/bytecode/Opcode.h +++ b/Source/JavaScriptCore/bytecode/Opcode.h @@ -48,9 +48,9 @@ namespace JSC { macro(op_convert_this, 3) \ \ macro(op_new_object, 2) \ - macro(op_new_array, 5) \ - macro(op_new_array_with_size, 4) \ - macro(op_new_array_buffer, 5) \ + macro(op_new_array, 4) \ + macro(op_new_array_with_size, 3) \ + macro(op_new_array_buffer, 4) \ macro(op_new_regexp, 3) \ macro(op_mov, 3) \ \ diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h index 656bc79ee..09ba9fdfa 100644 --- a/Source/JavaScriptCore/bytecode/SpeculatedType.h +++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h @@ -61,7 +61,6 @@ static const SpeculatedType SpecInt32 = 0x00800000; // It's definite static const SpeculatedType SpecDoubleReal = 0x01000000; // It's definitely a non-NaN double. static const SpeculatedType SpecDoubleNaN = 0x02000000; // It's definitely a NaN. static const SpeculatedType SpecDouble = 0x03000000; // It's either a non-NaN or a NaN double. -static const SpeculatedType SpecRealNumber = 0x01800000; // It's either an Int32 or a DoubleReal. static const SpeculatedType SpecNumber = 0x03800000; // It's either an Int32 or a Double. static const SpeculatedType SpecBoolean = 0x04000000; // It's definitely a Boolean. static const SpeculatedType SpecOther = 0x08000000; // It's definitely none of the above. @@ -229,16 +228,6 @@ inline bool isInt32Speculation(SpeculatedType value) return value == SpecInt32; } -inline bool isInt32SpeculationForArithmetic(SpeculatedType value) -{ - return !(value & SpecDouble); -} - -inline bool isInt32SpeculationExpectingDefined(SpeculatedType value) -{ - return isInt32Speculation(value & ~SpecOther); -} - inline bool isDoubleRealSpeculation(SpeculatedType value) { return value == SpecDoubleReal; @@ -249,26 +238,11 @@ inline bool isDoubleSpeculation(SpeculatedType value) return !!value && (value & SpecDouble) == value; } -inline bool isDoubleSpeculationForArithmetic(SpeculatedType value) -{ - return !!(value & SpecDouble); -} - -inline bool isRealNumberSpeculation(SpeculatedType value) -{ - return !!(value & SpecRealNumber) && !(value & ~SpecRealNumber); -} - inline bool isNumberSpeculation(SpeculatedType value) { return !!(value & SpecNumber) && !(value & ~SpecNumber); } -inline bool isNumberSpeculationExpectingDefined(SpeculatedType value) -{ - return isNumberSpeculation(value & ~SpecOther); -} - inline bool isBooleanSpeculation(SpeculatedType value) { return value == SpecBoolean; diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp index e98d4de0a..8aa48404a 100644 --- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp @@ -80,6 +80,8 @@ void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visito COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_codeBlockForCall); + visitor.append(&thisObject->m_codeBlockForConstruct); visitor.append(&thisObject->m_nameValue); visitor.append(&thisObject->m_symbolTableForCall); visitor.append(&thisObject->m_symbolTableForConstruct); @@ -110,16 +112,12 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(JSGlobalData { switch (specializationKind) { case CodeForCall: - if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get()) { - globalData.codeCache()->usedFunctionCode(globalData, codeBlock); - return codeBlock; - } + if (m_codeBlockForCall) + return m_codeBlockForCall.get(); break; case CodeForConstruct: - if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get()) { - globalData.codeCache()->usedFunctionCode(globalData, codeBlock); - return codeBlock; - } + if (m_codeBlockForConstruct) + return m_codeBlockForConstruct.get(); break; } @@ -130,11 +128,11 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(JSGlobalData switch (specializationKind) { case CodeForCall: - m_codeBlockForCall = PassWeak<UnlinkedFunctionCodeBlock>(result); + m_codeBlockForCall.set(globalData, this, result); m_symbolTableForCall.set(globalData, this, result->symbolTable()); break; case CodeForConstruct: - m_codeBlockForConstruct = PassWeak<UnlinkedFunctionCodeBlock>(result); + m_codeBlockForConstruct.set(globalData, this, result); m_symbolTableForConstruct.set(globalData, this, result->symbolTable()); break; } @@ -173,7 +171,6 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(JSGlobalData* globalData, Structure* struct , m_resolveOperationCount(0) , m_putToBaseOperationCount(1) , m_arrayProfileCount(0) - , m_arrayAllocationProfileCount(0) , m_valueProfileCount(0) , m_llintCallLinkInfoCount(0) #if ENABLE(BYTECODE_COMMENTS) diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h index 23937d773..bf3f5fdff 100644 --- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h +++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h @@ -36,7 +36,6 @@ #include "Nodes.h" #include "RegExp.h" #include "SpecialPointer.h" -#include "Weak.h" #include <wtf/RefCountedArray.h> #include <wtf/Vector.h> @@ -57,7 +56,6 @@ class UnlinkedFunctionCodeBlock; typedef unsigned UnlinkedValueProfile; typedef unsigned UnlinkedArrayProfile; -typedef unsigned UnlinkedArrayAllocationProfile; typedef unsigned UnlinkedLLIntCallLinkInfo; struct ExecutableInfo { @@ -109,7 +107,7 @@ public: FunctionExecutable* link(JSGlobalData&, const SourceCode&, size_t lineOffset, size_t sourceOffset); - void clearCodeForRecompilation() + void clearCode() { m_symbolTableForCall.clear(); m_symbolTableForConstruct.clear(); @@ -137,8 +135,8 @@ public: private: UnlinkedFunctionExecutable(JSGlobalData*, Structure*, const SourceCode&, FunctionBodyNode*); - Weak<UnlinkedFunctionCodeBlock> m_codeBlockForCall; - Weak<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; + WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall; + WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; unsigned m_numCapturedVariables : 29; bool m_forceUsesArguments : 1; @@ -394,8 +392,6 @@ public: UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; } unsigned numberOfArrayProfiles() { return m_arrayProfileCount; } - UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; } - unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; } UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; } unsigned numberOfValueProfiles() { return m_valueProfileCount; } @@ -522,7 +518,6 @@ private: unsigned m_resolveOperationCount; unsigned m_putToBaseOperationCount; unsigned m_arrayProfileCount; - unsigned m_arrayAllocationProfileCount; unsigned m_valueProfileCount; unsigned m_llintCallLinkInfoCount; diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index b1b9de6c1..b11872551 100644 --- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -716,15 +716,6 @@ UnlinkedArrayProfile BytecodeGenerator::newArrayProfile() #endif } -UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile() -{ -#if ENABLE(VALUE_PROFILER) - return m_codeBlock->addArrayAllocationProfile(); -#else - return 0; -#endif -} - UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID) { #if ENABLE(VALUE_PROFILER) @@ -1614,7 +1605,6 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen instructions().append(dst->index()); instructions().append(constantBufferIndex); instructions().append(length); - instructions().append(newArrayAllocationProfile()); return dst; } } @@ -1632,7 +1622,6 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen instructions().append(dst->index()); instructions().append(argv.size() ? argv[0]->index() : 0); // argv instructions().append(argv.size()); // argc - instructions().append(newArrayAllocationProfile()); return dst; } @@ -1768,14 +1757,12 @@ ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst, emitOpcode(op_new_array_with_size); instructions().append(dst->index()); instructions().append(callArguments.argumentRegister(0)->index()); - instructions().append(newArrayAllocationProfile()); } else { ASSERT(callArguments.argumentCountIncludingThis() == 1); emitOpcode(op_new_array); instructions().append(dst->index()); instructions().append(0); instructions().append(0); - instructions().append(newArrayAllocationProfile()); } } break; diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 2e7aa2035..828726dee 100644 --- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -523,7 +523,6 @@ namespace JSC { #endif void emitOpcode(OpcodeID); - UnlinkedArrayAllocationProfile newArrayAllocationProfile(); UnlinkedArrayProfile newArrayProfile(); UnlinkedValueProfile emitProfiledOpcode(OpcodeID); void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index); diff --git a/Source/JavaScriptCore/debugger/Debugger.cpp b/Source/JavaScriptCore/debugger/Debugger.cpp index 7eda52dc8..b14729146 100644 --- a/Source/JavaScriptCore/debugger/Debugger.cpp +++ b/Source/JavaScriptCore/debugger/Debugger.cpp @@ -80,7 +80,7 @@ inline void Recompiler::operator()(JSCell* cell) ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec(); executable->clearCodeIfNotCompiling(); - executable->clearUnlinkedCodeForRecompilationIfNotCompiling(); + executable->clearUnlinkedCodeIfNotCompiling(); if (m_debugger == function->scope()->globalObject()->debugger()) m_sourceProviders.add(executable->source().provider(), exec); } diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp index 02e578b29..e518c24a8 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp @@ -159,7 +159,7 @@ void AbstractState::initialize(Graph& graph) } } -bool AbstractState::endBasicBlock(MergeMode mergeMode) +bool AbstractState::endBasicBlock(MergeMode mergeMode, BranchDirection* branchDirectionPtr) { ASSERT(m_block); @@ -167,7 +167,6 @@ bool AbstractState::endBasicBlock(MergeMode mergeMode) block->cfaFoundConstants = m_foundConstants; block->cfaDidFinish = m_isValid; - block->cfaBranchDirection = m_branchDirection; if (!m_isValid) { reset(); @@ -196,8 +195,12 @@ bool AbstractState::endBasicBlock(MergeMode mergeMode) ASSERT(mergeMode != DontMerge || !changed); + BranchDirection branchDirection = m_branchDirection; + if (branchDirectionPtr) + *branchDirectionPtr = branchDirection; + #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - dataLog(" Branch direction = %s\n", branchDirectionToString(m_branchDirection)); + dataLog(" Branch direction = %s\n", branchDirectionToString(branchDirection)); #endif reset(); @@ -205,7 +208,7 @@ bool AbstractState::endBasicBlock(MergeMode mergeMode) if (mergeMode != MergeToSuccessors) return changed; - return mergeToSuccessors(m_graph, block); + return mergeToSuccessors(m_graph, block, branchDirection); } void AbstractState::reset() @@ -421,10 +424,7 @@ bool AbstractState::execute(unsigned indexInBlock) break; } speculateNumberUnary(node); - if (isInt32Speculation(forNode(node.child1()).m_type)) - forNode(nodeIndex).set(SpecDoubleReal); - else - forNode(nodeIndex).set(SpecDouble); + forNode(nodeIndex).set(SpecDouble); break; } @@ -448,13 +448,9 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(nodeIndex).set(SpecInt32); break; } - if (Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()])) { + if (Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()])) { speculateNumberBinary(node); - if (isRealNumberSpeculation(forNode(node.child1()).m_type) - && isRealNumberSpeculation(forNode(node.child2()).m_type)) - forNode(nodeIndex).set(SpecDoubleReal); - else - forNode(nodeIndex).set(SpecDouble); + forNode(nodeIndex).set(SpecDouble); break; } if (node.op() == ValueAdd) { @@ -526,11 +522,7 @@ bool AbstractState::execute(unsigned indexInBlock) break; } speculateNumberBinary(node); - if (isRealNumberSpeculation(forNode(node.child1()).m_type) - || isRealNumberSpeculation(forNode(node.child2()).m_type)) - forNode(nodeIndex).set(SpecDoubleReal); - else - forNode(nodeIndex).set(SpecDouble); + forNode(nodeIndex).set(SpecDouble); break; } @@ -568,7 +560,7 @@ bool AbstractState::execute(unsigned indexInBlock) break; } } - if (Node::shouldSpeculateIntegerForArithmetic( + if (Node::shouldSpeculateInteger( m_graph[node.child1()], m_graph[node.child2()]) && node.canSpeculateInteger()) { speculateInt32Binary(node, true); // forcing can-exit, which is a bit on the conservative side. @@ -588,7 +580,7 @@ bool AbstractState::execute(unsigned indexInBlock) node.setCanExit(false); break; } - if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic() + if (m_graph[node.child1()].shouldSpeculateInteger() && node.canSpeculateInteger()) { speculateInt32Unary(node, true); forNode(nodeIndex).set(SpecInt32); @@ -613,22 +605,12 @@ bool AbstractState::execute(unsigned indexInBlock) } case LogicalNot: { - // First check if we can fold because the source is a constant. JSValue childConst = forNode(node.child1()).value(); if (childConst && trySetConstant(nodeIndex, jsBoolean(!childConst.toBoolean(m_codeBlock->globalObjectFor(node.codeOrigin)->globalExec())))) { m_foundConstants = true; node.setCanExit(false); break; } - // Next check if we can fold because we know that the source is an object or string and does not equal undefined. - if (isCellSpeculation(forNode(node.child1()).m_type) - && forNode(node.child1()).m_currentKnownStructure.hasSingleton() - && !forNode(node.child1()).m_currentKnownStructure.singleton()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin)) - && trySetConstant(nodeIndex, jsBoolean(false))) { - m_foundConstants = true; - node.setCanExit(false); - break; - } Node& child = m_graph[node.child1()]; if (isBooleanSpeculation(child.prediction())) speculateBooleanUnary(node); @@ -696,13 +678,12 @@ bool AbstractState::execute(unsigned indexInBlock) case CompareGreater: case CompareGreaterEq: case CompareEq: { - bool constantWasSet = false; - JSValue leftConst = forNode(node.child1()).value(); JSValue rightConst = forNode(node.child2()).value(); if (leftConst && rightConst && leftConst.isNumber() && rightConst.isNumber()) { double a = leftConst.asNumber(); double b = rightConst.asNumber(); + bool constantWasSet; switch (node.op()) { case CompareLess: constantWasSet = trySetConstant(nodeIndex, jsBoolean(a < b)); @@ -724,20 +705,11 @@ bool AbstractState::execute(unsigned indexInBlock) constantWasSet = false; break; } - } - - if (!constantWasSet && node.op() == CompareEq) { - SpeculatedType leftType = forNode(node.child1()).m_type; - SpeculatedType rightType = forNode(node.child2()).m_type; - if ((isInt32Speculation(leftType) && isOtherSpeculation(rightType)) - || (isOtherSpeculation(leftType) && isInt32Speculation(rightType))) - constantWasSet = trySetConstant(nodeIndex, jsBoolean(false)); - } - - if (constantWasSet) { - m_foundConstants = true; - node.setCanExit(false); - break; + if (constantWasSet) { + m_foundConstants = true; + node.setCanExit(false); + break; + } } forNode(nodeIndex).set(SpecBoolean); @@ -870,7 +842,6 @@ bool AbstractState::execute(unsigned indexInBlock) switch (node.arrayMode().type()) { case Array::SelectUsingPredictions: case Array::Unprofiled: - case Array::Undecided: ASSERT_NOT_REACHED(); break; case Array::ForceExit: @@ -888,22 +859,6 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(node.child2()).filter(SpecInt32); forNode(nodeIndex).makeTop(); break; - case Array::Int32: - forNode(node.child2()).filter(SpecInt32); - if (node.arrayMode().isOutOfBounds()) { - clobberWorld(node.codeOrigin, indexInBlock); - forNode(nodeIndex).makeTop(); - } else - forNode(nodeIndex).set(SpecInt32); - break; - case Array::Double: - forNode(node.child2()).filter(SpecInt32); - if (node.arrayMode().isOutOfBounds()) { - clobberWorld(node.codeOrigin, indexInBlock); - forNode(nodeIndex).makeTop(); - } else - forNode(nodeIndex).set(SpecDoubleReal); - break; case Array::Contiguous: case Array::ArrayStorage: case Array::SlowPutArrayStorage: @@ -971,20 +926,6 @@ bool AbstractState::execute(unsigned indexInBlock) case Array::Generic: clobberWorld(node.codeOrigin, indexInBlock); break; - case Array::Int32: - forNode(child1).filter(SpecCell); - forNode(child2).filter(SpecInt32); - forNode(child3).filter(SpecInt32); - if (node.arrayMode().isOutOfBounds()) - clobberWorld(node.codeOrigin, indexInBlock); - break; - case Array::Double: - forNode(child1).filter(SpecCell); - forNode(child2).filter(SpecInt32); - forNode(child3).filter(SpecRealNumber); - if (node.arrayMode().isOutOfBounds()) - clobberWorld(node.codeOrigin, indexInBlock); - break; case Array::Contiguous: case Array::ArrayStorage: forNode(child1).filter(SpecCell); @@ -1077,16 +1018,6 @@ bool AbstractState::execute(unsigned indexInBlock) case ArrayPush: node.setCanExit(true); - switch (node.arrayMode().type()) { - case Array::Int32: - forNode(node.child2()).filter(SpecInt32); - break; - case Array::Double: - forNode(node.child2()).filter(SpecRealNumber); - break; - default: - break; - } clobberWorld(node.codeOrigin, indexInBlock); forNode(nodeIndex).set(SpecNumber); break; @@ -1112,7 +1043,6 @@ bool AbstractState::execute(unsigned indexInBlock) break; case Branch: { - // First check if we can fold because the source is a constant. JSValue value = forNode(node.child1()).value(); if (value) { bool booleanValue = value.toBoolean(m_codeBlock->globalObjectFor(node.codeOrigin)->globalExec()); @@ -1123,14 +1053,6 @@ bool AbstractState::execute(unsigned indexInBlock) node.setCanExit(false); break; } - // Next check if we can fold because we know that the source is an object or string and does not equal undefined. - if (isCellSpeculation(forNode(node.child1()).m_type) - && forNode(node.child1()).m_currentKnownStructure.hasSingleton() - && !forNode(node.child1()).m_currentKnownStructure.singleton()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin))) { - m_branchDirection = TakeTrue; - node.setCanExit(false); - break; - } // FIXME: The above handles the trivial cases of sparse conditional // constant propagation, but we can do better: // 1) If the abstract value does not have a concrete value but describes @@ -1200,13 +1122,13 @@ bool AbstractState::execute(unsigned indexInBlock) case NewArray: node.setCanExit(true); - forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())); + forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure()); m_haveStructures = true; break; case NewArrayBuffer: node.setCanExit(true); - forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())); + forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure()); m_haveStructures = true; break; @@ -1462,11 +1384,11 @@ bool AbstractState::execute(unsigned indexInBlock) case Array::String: forNode(node.child1()).filter(SpecString); break; - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: case Array::SlowPutArrayStorage: + // This doesn't filter anything meaningful right now. We may want to add + // CFA tracking of array mode speculations, but we don't have that, yet. forNode(node.child1()).filter(SpecCell); break; case Array::Arguments: @@ -1800,7 +1722,7 @@ inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to) } inline bool AbstractState::mergeToSuccessors( - Graph& graph, BasicBlock* basicBlock) + Graph& graph, BasicBlock* basicBlock, BranchDirection branchDirection) { Node& terminal = graph[basicBlock->last()]; @@ -1808,7 +1730,7 @@ inline bool AbstractState::mergeToSuccessors( switch (terminal.op()) { case Jump: { - ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection); + ASSERT(branchDirection == InvalidBranchDirection); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Merging to block #%u.\n", terminal.takenBlockIndex()); #endif @@ -1816,17 +1738,17 @@ inline bool AbstractState::mergeToSuccessors( } case Branch: { - ASSERT(basicBlock->cfaBranchDirection != InvalidBranchDirection); + ASSERT(branchDirection != InvalidBranchDirection); bool changed = false; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Merging to block #%u.\n", terminal.takenBlockIndex()); #endif - if (basicBlock->cfaBranchDirection != TakeFalse) + if (branchDirection != TakeFalse) changed |= merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get()); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Merging to block #%u.\n", terminal.notTakenBlockIndex()); #endif - if (basicBlock->cfaBranchDirection != TakeTrue) + if (branchDirection != TakeTrue) changed |= merge(basicBlock, graph.m_blocks[terminal.notTakenBlockIndex()].get()); return changed; } @@ -1834,7 +1756,7 @@ inline bool AbstractState::mergeToSuccessors( case Return: case Throw: case ThrowReferenceError: - ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection); + ASSERT(branchDirection == InvalidBranchDirection); return false; default: diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h index 0e33140c0..ec1a06231 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.h +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +31,6 @@ #if ENABLE(DFG_JIT) #include "DFGAbstractValue.h" -#include "DFGBranchDirection.h" #include "DFGGraph.h" #include "DFGNode.h" #include <wtf/Vector.h> @@ -93,6 +92,36 @@ public: MergeToSuccessors }; + enum BranchDirection { + // This is not a branch and so there is no branch direction, or + // the branch direction has yet to be set. + InvalidBranchDirection, + + // The branch takes the true case. + TakeTrue, + + // The branch takes the false case. + TakeFalse, + + // For all we know, the branch could go either direction, so we + // have to assume the worst. + TakeBoth + }; + + static const char* branchDirectionToString(BranchDirection branchDirection) + { + switch (branchDirection) { + case InvalidBranchDirection: + return "Invalid"; + case TakeTrue: + return "TakeTrue"; + case TakeFalse: + return "TakeFalse"; + case TakeBoth: + return "TakeBoth"; + } + } + AbstractState(Graph&); ~AbstractState(); @@ -145,7 +174,11 @@ public: // A true return means that you must revisit (at least) the successor // blocks. This also sets cfaShouldRevisit to true for basic blocks // that must be visited next. - bool endBasicBlock(MergeMode); + // + // If you'd like to know what direction the branch at the end of the + // basic block is thought to have taken, you can pass a non-0 pointer + // for BranchDirection. + bool endBasicBlock(MergeMode, BranchDirection* = 0); // Reset the AbstractState. This throws away any results, and at this point // you can safely call beginBasicBlock() on any basic block. @@ -178,8 +211,8 @@ public: // successors. Returns true if any of the successors' states changed. Note // that this is automatically called in endBasicBlock() if MergeMode is // MergeToSuccessors. - bool mergeToSuccessors(Graph&, BasicBlock*); - + bool mergeToSuccessors(Graph&, BasicBlock*, BranchDirection); + void dump(FILE* out); private: diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp index 0d15b9a30..699902a16 100644 --- a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp +++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp @@ -34,46 +34,19 @@ namespace JSC { namespace DFG { ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, bool makeSafe) { - ArrayModes observed = profile->observedArrayModes(); - switch (observed) { + switch (profile->observedArrayModes()) { case 0: return ArrayMode(Array::Unprofiled); case asArrayModes(NonArray): if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) - return ArrayMode(Array::Undecided, Array::NonArray, Array::OutOfBounds, Array::Convert); + return ArrayMode(Array::Contiguous, Array::NonArray, Array::OutOfBounds, Array::Convert); // FIXME: we don't know whether to go to contiguous or array storage. We're making a static guess here. In future we should use exit profiling for this. return ArrayMode(Array::SelectUsingPredictions); - - case asArrayModes(ArrayWithUndecided): - if (action == Array::Write) - return ArrayMode(Array::Undecided, Array::Array, Array::OutOfBounds, Array::Convert); - return ArrayMode(Array::Generic); - - case asArrayModes(NonArray) | asArrayModes(ArrayWithUndecided): - if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) - return ArrayMode(Array::Undecided, Array::PossiblyArray, Array::OutOfBounds, Array::Convert); - return ArrayMode(Array::SelectUsingPredictions); - - case asArrayModes(NonArrayWithInt32): - return ArrayMode(Array::Int32, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe); - case asArrayModes(ArrayWithInt32): - return ArrayMode(Array::Int32, Array::Array, Array::AsIs).withProfile(profile, makeSafe); - case asArrayModes(NonArrayWithInt32) | asArrayModes(ArrayWithInt32): - return ArrayMode(Array::Int32, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe); - - case asArrayModes(NonArrayWithDouble): - return ArrayMode(Array::Double, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe); - case asArrayModes(ArrayWithDouble): - return ArrayMode(Array::Double, Array::Array, Array::AsIs).withProfile(profile, makeSafe); - case asArrayModes(NonArrayWithDouble) | asArrayModes(ArrayWithDouble): - return ArrayMode(Array::Double, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe); - case asArrayModes(NonArrayWithContiguous): return ArrayMode(Array::Contiguous, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe); case asArrayModes(ArrayWithContiguous): return ArrayMode(Array::Contiguous, Array::Array, Array::AsIs).withProfile(profile, makeSafe); case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous): return ArrayMode(Array::Contiguous, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe); - case asArrayModes(NonArrayWithArrayStorage): return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe); case asArrayModes(NonArrayWithSlowPutArrayStorage): @@ -89,39 +62,36 @@ ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, b case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): return ArrayMode(Array::SlowPutArrayStorage, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe); - + case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage): + return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::Convert).withProfile(profile, makeSafe); + case asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage): + return ArrayMode(Array::ArrayStorage, Array::Array, Array::Convert).withProfile(profile, makeSafe); + case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage): + return ArrayMode(Array::ArrayStorage, Array::PossiblyArray, Array::Convert).withProfile(profile, makeSafe); + case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous): + if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) + return ArrayMode(Array::Contiguous, Array::NonArray, Array::OutOfBounds, Array::Convert); + return ArrayMode(Array::SelectUsingPredictions); + case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage): + case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage): + if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) + return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::OutOfBounds, Array::Convert); + return ArrayMode(Array::SelectUsingPredictions); + case asArrayModes(NonArray) | asArrayModes(NonArrayWithSlowPutArrayStorage): + case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage): + if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) + return ArrayMode(Array::SlowPutArrayStorage, Array::NonArray, Array::OutOfBounds, Array::Convert); + return ArrayMode(Array::SelectUsingPredictions); default: - if ((observed & asArrayModes(NonArray)) && profile->mayInterceptIndexedAccesses()) - return ArrayMode(Array::SelectUsingPredictions); - - Array::Type type; - Array::Class arrayClass; - - if (shouldUseSlowPutArrayStorage(observed)) - type = Array::SlowPutArrayStorage; - else if (shouldUseFastArrayStorage(observed)) - type = Array::ArrayStorage; - else if (shouldUseContiguous(observed)) - type = Array::Contiguous; - else if (shouldUseDouble(observed)) - type = Array::Double; - else if (shouldUseInt32(observed)) - type = Array::Int32; - else - type = Array::Undecided; - - if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) - arrayClass = Array::Array; - else if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage))) - arrayClass = Array::NonArray; - else - arrayClass = Array::PossiblyArray; - - return ArrayMode(type, arrayClass, Array::Convert).withProfile(profile, makeSafe); + // We know that this is possibly a kind of array for which, though there is no + // useful data in the array profile, we may be able to extract useful data from + // the value profiles of the inputs. Hence, we leave it as undecided, and let + // the predictions propagator decide later. + return ArrayMode(Array::SelectUsingPredictions); } } -ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, SpeculatedType value) const +ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index) const { if (!base || !index) { // It can be that we had a legitimate arrayMode but no incoming predictions. That'll @@ -134,85 +104,49 @@ ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, Speculate if (!isInt32Speculation(index) || !isCellSpeculation(base)) return ArrayMode(Array::Generic); - switch (type()) { - case Array::Unprofiled: + if (type() == Array::Unprofiled) { + // If the indexing type wasn't recorded in the array profile but the values are + // base=cell property=int, then we know that this access didn't execute. return ArrayMode(Array::ForceExit); - - case Array::Undecided: - if (!value) - return withType(Array::ForceExit); - if (isInt32Speculation(value)) - return withTypeAndConversion(Array::Int32, Array::Convert); - if (isNumberSpeculation(value)) - return withTypeAndConversion(Array::Double, Array::Convert); - return withTypeAndConversion(Array::Contiguous, Array::Convert); - - case Array::Int32: - if (!value || isInt32Speculation(value)) - return *this; - if (isNumberSpeculation(value)) - return withTypeAndConversion(Array::Double, Array::Convert); - return withTypeAndConversion(Array::Contiguous, Array::Convert); - - case Array::Double: - if (!value || isNumberSpeculation(value)) - return *this; - return withTypeAndConversion(Array::Contiguous, Array::Convert); - - case Array::SelectUsingPredictions: - if (isStringSpeculation(base)) - return ArrayMode(Array::String); - - if (isArgumentsSpeculation(base)) - return ArrayMode(Array::Arguments); - - if (isInt8ArraySpeculation(base)) - return ArrayMode(Array::Int8Array); - - if (isInt16ArraySpeculation(base)) - return ArrayMode(Array::Int16Array); - - if (isInt32ArraySpeculation(base)) - return ArrayMode(Array::Int32Array); - - if (isUint8ArraySpeculation(base)) - return ArrayMode(Array::Uint8Array); - - if (isUint8ClampedArraySpeculation(base)) - return ArrayMode(Array::Uint8ClampedArray); - - if (isUint16ArraySpeculation(base)) - return ArrayMode(Array::Uint16Array); - - if (isUint32ArraySpeculation(base)) - return ArrayMode(Array::Uint32Array); - - if (isFloat32ArraySpeculation(base)) - return ArrayMode(Array::Float32Array); - - if (isFloat64ArraySpeculation(base)) - return ArrayMode(Array::Float64Array); - - return ArrayMode(Array::Generic); - - default: - return *this; - } -} - -bool ArrayMode::alreadyChecked(AbstractValue& value, IndexingType shape) const -{ - if (isJSArray()) { - if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray))) - return true; - return value.m_currentKnownStructure.hasSingleton() - && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape - && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); } - if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape) | asArrayModes(shape | IsArray))) - return true; - return value.m_currentKnownStructure.hasSingleton() - && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape; + + if (type() != Array::SelectUsingPredictions) + return *this; + + if (isStringSpeculation(base)) + return ArrayMode(Array::String); + + if (isArgumentsSpeculation(base)) + return ArrayMode(Array::Arguments); + + if (isInt8ArraySpeculation(base)) + return ArrayMode(Array::Int8Array); + + if (isInt16ArraySpeculation(base)) + return ArrayMode(Array::Int16Array); + + if (isInt32ArraySpeculation(base)) + return ArrayMode(Array::Int32Array); + + if (isUint8ArraySpeculation(base)) + return ArrayMode(Array::Uint8Array); + + if (isUint8ClampedArraySpeculation(base)) + return ArrayMode(Array::Uint8ClampedArray); + + if (isUint16ArraySpeculation(base)) + return ArrayMode(Array::Uint16Array); + + if (isUint32ArraySpeculation(base)) + return ArrayMode(Array::Uint32Array); + + if (isFloat32ArraySpeculation(base)) + return ArrayMode(Array::Float32Array); + + if (isFloat64ArraySpeculation(base)) + return ArrayMode(Array::Float64Array); + + return ArrayMode(Array::Generic); } bool ArrayMode::alreadyChecked(AbstractValue& value) const @@ -227,17 +161,31 @@ bool ArrayMode::alreadyChecked(AbstractValue& value) const case Array::String: return speculationChecked(value.m_type, SpecString); - case Array::Int32: - return alreadyChecked(value, Int32Shape); - - case Array::Double: - return alreadyChecked(value, DoubleShape); - case Array::Contiguous: - return alreadyChecked(value, ContiguousShape); + if (isJSArray()) { + if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithContiguous))) + return true; + return value.m_currentKnownStructure.hasSingleton() + && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()) + && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); + } + if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous))) + return true; + return value.m_currentKnownStructure.hasSingleton() + && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()); case Array::ArrayStorage: - return alreadyChecked(value, ArrayStorageShape); + if (isJSArray()) { + if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage))) + return true; + return value.m_currentKnownStructure.hasSingleton() + && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) + && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); + } + if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage))) + return true; + return value.m_currentKnownStructure.hasSingleton() + && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()); case Array::SlowPutArrayStorage: if (isJSArray()) { @@ -284,7 +232,6 @@ bool ArrayMode::alreadyChecked(AbstractValue& value) const case Array::SelectUsingPredictions: case Array::Unprofiled: - case Array::Undecided: break; } @@ -305,12 +252,6 @@ const char* arrayTypeToString(Array::Type type) return "ForceExit"; case Array::String: return "String"; - case Array::Undecided: - return "Undecided"; - case Array::Int32: - return "Int32"; - case Array::Double: - return "Double"; case Array::Contiguous: return "Contiguous"; case Array::ArrayStorage: diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.h b/Source/JavaScriptCore/dfg/DFGArrayMode.h index 206d689f2..615965c92 100644 --- a/Source/JavaScriptCore/dfg/DFGArrayMode.h +++ b/Source/JavaScriptCore/dfg/DFGArrayMode.h @@ -52,10 +52,7 @@ enum Type { ForceExit, // Implies that we have no idea how to execute this operation, so we should just give up. Generic, String, - - Undecided, - Int32, - Double, + Contiguous, ArrayStorage, SlowPutArrayStorage, @@ -84,6 +81,7 @@ enum Speculation { ToHole, OutOfBounds }; + enum Conversion { AsIs, Convert @@ -171,17 +169,7 @@ public: return ArrayMode(type(), myArrayClass, mySpeculation, conversion()); } - ArrayMode withType(Array::Type type) const - { - return ArrayMode(type, arrayClass(), speculation(), conversion()); - } - - ArrayMode withTypeAndConversion(Array::Type type, Array::Conversion conversion) const - { - return ArrayMode(type, arrayClass(), speculation(), conversion); - } - - ArrayMode refine(SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone) const; + ArrayMode refine(SpeculatedType base, SpeculatedType index) const; bool alreadyChecked(AbstractValue&) const; @@ -190,8 +178,6 @@ public: bool usesButterfly() const { switch (type()) { - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: case Array::SlowPutArrayStorage: @@ -277,7 +263,6 @@ public: case Array::Unprofiled: case Array::ForceExit: case Array::Generic: - case Array::Undecided: return false; default: return true; @@ -292,8 +277,6 @@ public: case Array::ForceExit: case Array::Generic: return false; - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: case Array::SlowPutArrayStorage: @@ -326,10 +309,6 @@ public: switch (type()) { case Array::Generic: return ALL_ARRAY_MODES; - case Array::Int32: - return arrayModesWithIndexingShape(Int32Shape); - case Array::Double: - return arrayModesWithIndexingShape(DoubleShape); case Array::Contiguous: return arrayModesWithIndexingShape(ContiguousShape); case Array::ArrayStorage: @@ -375,8 +354,6 @@ private: } } - bool alreadyChecked(AbstractValue&, IndexingType shape) const; - union { struct { uint8_t type; diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h index 6f348f2e1..441e2e75e 100644 --- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h +++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h @@ -29,7 +29,6 @@ #if ENABLE(DFG_JIT) #include "DFGAbstractValue.h" -#include "DFGBranchDirection.h" #include "DFGNode.h" #include "Operands.h" #include <wtf/OwnPtr.h> @@ -47,7 +46,6 @@ struct BasicBlock : Vector<NodeIndex, 8> { , cfaShouldRevisit(false) , cfaFoundConstants(false) , cfaDidFinish(true) - , cfaBranchDirection(InvalidBranchDirection) #if !ASSERT_DISABLED , isLinked(false) #endif @@ -107,7 +105,6 @@ struct BasicBlock : Vector<NodeIndex, 8> { bool cfaShouldRevisit; bool cfaFoundConstants; bool cfaDidFinish; - BranchDirection cfaBranchDirection; #if !ASSERT_DISABLED bool isLinked; #endif diff --git a/Source/JavaScriptCore/dfg/DFGBranchDirection.h b/Source/JavaScriptCore/dfg/DFGBranchDirection.h deleted file mode 100644 index 8bbe3c635..000000000 --- a/Source/JavaScriptCore/dfg/DFGBranchDirection.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef DFGBranchDirection_h -#define DFGBranchDirection_h - -#include <wtf/Platform.h> - -#if ENABLE(DFG_JIT) - -namespace JSC { namespace DFG { - -enum BranchDirection { - // This is not a branch and so there is no branch direction, or - // the branch direction has yet to be set. - InvalidBranchDirection, - - // The branch takes the true case. - TakeTrue, - - // The branch takes the false case. - TakeFalse, - - // For all we know, the branch could go either direction, so we - // have to assume the worst. - TakeBoth -}; - -static inline const char* branchDirectionToString(BranchDirection branchDirection) -{ - switch (branchDirection) { - case InvalidBranchDirection: - return "Invalid"; - case TakeTrue: - return "TakeTrue"; - case TakeFalse: - return "TakeFalse"; - case TakeBoth: - return "TakeBoth"; - } -} - -static inline bool isKnownDirection(BranchDirection branchDirection) -{ - switch (branchDirection) { - case TakeTrue: - case TakeFalse: - return true; - default: - return false; - } -} - -static inline bool branchCondition(BranchDirection branchDirection) -{ - if (branchDirection == TakeTrue) - return true; - ASSERT(branchDirection == TakeFalse); - return false; -} - -} } // namespace JSC::DFG - -#endif // ENABLE(DFG_JIT) - -#endif // DFGBranchDirection_h diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp index 142b8ab95..70aa2b637 100644 --- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp +++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp @@ -905,15 +905,10 @@ private: return getPrediction(m_graph.size(), m_currentProfilingIndex); } - ArrayMode getArrayMode(ArrayProfile* profile, Array::Action action) - { - profile->computeUpdatedPrediction(m_inlineStackTop->m_codeBlock); - return ArrayMode::fromObserved(profile, action, false); - } - ArrayMode getArrayMode(ArrayProfile* profile) { - return getArrayMode(profile, Array::Read); + profile->computeUpdatedPrediction(m_inlineStackTop->m_codeBlock); + return ArrayMode::fromObserved(profile, Array::Read, false); } ArrayMode getArrayModeAndEmitChecks(ArrayProfile* profile, Array::Action action, NodeIndex base) @@ -1654,12 +1649,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins return false; ArrayMode arrayMode = getArrayMode(m_currentInstruction[5].u.arrayProfile); - if (!arrayMode.isJSArray()) - return false; switch (arrayMode.type()) { - case Array::Undecided: - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: { NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1))); @@ -1679,11 +1669,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins return false; ArrayMode arrayMode = getArrayMode(m_currentInstruction[5].u.arrayProfile); - if (!arrayMode.isJSArray()) - return false; switch (arrayMode.type()) { - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: { NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0))); @@ -1768,7 +1754,7 @@ bool ByteCodeParser::handleConstantInternalFunction( if (argumentCountIncludingThis == 2) { setIntrinsicResult( usesResult, resultOperand, - addToGraph(NewArrayWithSize, OpInfo(ArrayWithUndecided), get(registerOffset + argumentToOperand(1)))); + addToGraph(NewArrayWithSize, get(registerOffset + argumentToOperand(1)))); return true; } @@ -1776,7 +1762,7 @@ bool ByteCodeParser::handleConstantInternalFunction( addVarArgChild(get(registerOffset + argumentToOperand(i))); setIntrinsicResult( usesResult, resultOperand, - addToGraph(Node::VarArg, NewArray, OpInfo(ArrayWithUndecided), OpInfo(0))); + addToGraph(Node::VarArg, NewArray, OpInfo(0), OpInfo(0))); return true; } @@ -2136,37 +2122,24 @@ bool ByteCodeParser::parseBlock(unsigned limit) case op_new_array: { int startOperand = currentInstruction[2].u.operand; int numOperands = currentInstruction[3].u.operand; - ArrayAllocationProfile* profile = currentInstruction[4].u.arrayAllocationProfile; for (int operandIdx = startOperand; operandIdx < startOperand + numOperands; ++operandIdx) addVarArgChild(get(operandIdx)); - set(currentInstruction[1].u.operand, addToGraph(Node::VarArg, NewArray, OpInfo(profile->selectIndexingType()), OpInfo(0))); + set(currentInstruction[1].u.operand, addToGraph(Node::VarArg, NewArray, OpInfo(0), OpInfo(0))); NEXT_OPCODE(op_new_array); } case op_new_array_with_size: { int lengthOperand = currentInstruction[2].u.operand; - ArrayAllocationProfile* profile = currentInstruction[3].u.arrayAllocationProfile; - set(currentInstruction[1].u.operand, addToGraph(NewArrayWithSize, OpInfo(profile->selectIndexingType()), get(lengthOperand))); + set(currentInstruction[1].u.operand, addToGraph(NewArrayWithSize, get(lengthOperand))); NEXT_OPCODE(op_new_array_with_size); } case op_new_array_buffer: { int startConstant = currentInstruction[2].u.operand; int numConstants = currentInstruction[3].u.operand; - ArrayAllocationProfile* profile = currentInstruction[4].u.arrayAllocationProfile; NewArrayBufferData data; data.startConstant = m_inlineStackTop->m_constantBufferRemap[startConstant]; data.numConstants = numConstants; - data.indexingType = profile->selectIndexingType(); - - // If this statement has never executed, we'll have the wrong indexing type in the profile. - for (int i = 0; i < numConstants; ++i) { - data.indexingType = - leastUpperBoundOfIndexingTypeAndValue( - data.indexingType, - m_codeBlock->constantBuffer(data.startConstant)[i]); - } - m_graph.m_newArrayBufferData.append(data); set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(&m_graph.m_newArrayBufferData.last()))); NEXT_OPCODE(op_new_array_buffer); diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h index 308dde5a6..a2570b7ea 100644 --- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h +++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h @@ -210,15 +210,6 @@ public: addCallArgument(arg3); } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3) - { - resetCallArguments(); - addCallArgument(GPRInfo::callFrameRegister); - addCallArgument(arg1); - addCallArgument(arg2); - addCallArgument(arg3); - } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3) { resetCallArguments(); @@ -277,16 +268,6 @@ public: addCallArgument(arg4); } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4) - { - resetCallArguments(); - addCallArgument(GPRInfo::callFrameRegister); - addCallArgument(arg1); - addCallArgument(arg2); - addCallArgument(arg3); - addCallArgument(arg4); - } - ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3) { resetCallArguments(); @@ -336,23 +317,6 @@ public: addCallArgument(arg4); addCallArgument(arg5); } - - ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) - { - resetCallArguments(); - addCallArgument(GPRInfo::callFrameRegister); - addCallArgument(arg1); - addCallArgument(arg2); - } - - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) - { - resetCallArguments(); - addCallArgument(GPRInfo::callFrameRegister); - addCallArgument(arg1); - addCallArgument(arg2); - addCallArgument(arg3); - } #endif // !NUMBER_OF_ARGUMENT_REGISTERS // These methods are suitable for any calling convention that provides for // at least 4 argument registers, e.g. X86_64, ARMv7. @@ -499,20 +463,6 @@ public: { setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2); } - - ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) - { - moveDouble(arg1, FPRInfo::argumentFPR0); - move(arg2, GPRInfo::argumentGPR1); - move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); - } - - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) - { - moveDouble(arg3, FPRInfo::argumentFPR0); - setupStubArguments(arg1, arg2); - move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); - } #elif CPU(ARM) #if CPU(ARM_HARDFP) ALWAYS_INLINE void setupArguments(FPRReg arg1) @@ -546,21 +496,6 @@ public: assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1); assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2); } - - ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) - { - move(arg2, GPRInfo::argumentGPR3); - assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1); - move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); - } - - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) - { - setupStubArguments(arg1, arg2); - move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); - assembler().vmov(GPRInfo::argumentGPR3, GPRInfo::nonArgGPR0, arg3); - poke(GPRInfo::nonArgGPR0); - } #endif // CPU(ARM_HARDFP) #else #error "DFG JIT not supported on this platform." @@ -700,13 +635,6 @@ public: move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3) - { - setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3); - move(arg2, GPRInfo::argumentGPR2); - move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); - } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3) { move(arg1, GPRInfo::argumentGPR1); @@ -795,12 +723,6 @@ public: setupArgumentsWithExecState(arg1, arg2, arg3); } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4) - { - poke(arg4); - setupArgumentsWithExecState(arg1, arg2, arg3); - } - ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) { poke(arg4); diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp index e3827d8ad..e0d973992 100644 --- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp @@ -99,8 +99,9 @@ public: case Branch: { // Branch on constant -> jettison the not-taken block and merge. - if (isKnownDirection(block->cfaBranchDirection)) { - bool condition = branchCondition(block->cfaBranchDirection); + if (m_graph[m_graph[block->last()].child1()].hasConstant()) { + bool condition = + m_graph.valueOfJSConstant(m_graph[block->last()].child1().index()).toBoolean(m_graph.globalObjectFor(m_graph[block->last()].codeOrigin)->globalExec()); BasicBlock* targetBlock = m_graph.m_blocks[ m_graph.successorForCondition(block, condition)].get(); if (targetBlock->m_predecessors.size() == 1) { @@ -729,7 +730,6 @@ private: } firstBlock->valuesAtTail = secondBlock->valuesAtTail; - firstBlock->cfaBranchDirection = secondBlock->cfaBranchDirection; m_graph.m_blocks[secondBlockIndex].clear(); } diff --git a/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h b/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h index 03713b6c5..46d5f44cb 100644 --- a/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h +++ b/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h @@ -61,7 +61,7 @@ protected: jit->silentSpill(m_plans[i]); jit->callOperation(m_function, m_resultGPR, m_structure, m_size); GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); - for (unsigned i = m_plans.size(); i--;) + for (unsigned i = 0; i < m_plans.size(); ++i) jit->silentFill(m_plans[i], canTrample); jit->m_jit.loadPtr(MacroAssembler::Address(m_resultGPR, JSObject::butterflyOffset()), m_storageGPR); jumpTo(jit); @@ -106,7 +106,7 @@ protected: done.link(&jit->m_jit); jit->callOperation(m_function, m_resultGPR, scratchGPR, m_sizeGPR); GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); - for (unsigned i = m_plans.size(); i--;) + for (unsigned i = 0; i < m_plans.size(); ++i) jit->silentFill(m_plans[i], canTrample); jumpTo(jit); } diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index 621d6e96a..5a76aa8df 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -145,30 +145,7 @@ private: } case ArrayPush: { - // May need to refine the array mode in case the value prediction contravenes - // the array prediction. For example, we may have evidence showing that the - // array is in Int32 mode, but the value we're storing is likely to be a double. - // Then we should turn this into a conversion to Double array followed by the - // push. On the other hand, we absolutely don't want to refine based on the - // base prediction. If it has non-cell garbage in it, then we want that to be - // ignored. That's because ArrayPush can't handle any array modes that aren't - // array-related - so if refine() turned this into a "Generic" ArrayPush then - // that would break things. - node.setArrayMode( - node.arrayMode().refine( - m_graph[node.child1()].prediction() & SpecCell, - SpecInt32, - m_graph[node.child2()].prediction())); blessArrayOperation(node.child1(), node.child2(), 2); - - Node* nodePtr = &m_graph[m_compileIndex]; - switch (nodePtr->arrayMode().type()) { - case Array::Double: - fixDoubleEdge(1); - break; - default: - break; - } break; } @@ -259,7 +236,7 @@ private: case ValueAdd: { if (m_graph.addShouldSpeculateInteger(node)) break; - if (!Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()])) + if (!Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()])) break; fixDoubleEdge(0); fixDoubleEdge(1); @@ -285,7 +262,7 @@ private: case ArithMin: case ArithMax: case ArithMod: { - if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) + if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]) && node.canSpeculateInteger()) break; fixDoubleEdge(0); @@ -302,7 +279,7 @@ private: } case ArithDiv: { - if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) + if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]) && node.canSpeculateInteger()) { if (isX86()) break; @@ -330,7 +307,7 @@ private: } case ArithAbs: { - if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic() + if (m_graph[node.child1()].shouldSpeculateInteger() && node.canSpeculateInteger()) break; fixDoubleEdge(0); @@ -351,17 +328,13 @@ private: node.setArrayMode( node.arrayMode().refine( m_graph[child1].prediction(), - m_graph[child2].prediction(), - m_graph[child3].prediction())); + m_graph[child2].prediction())); blessArrayOperation(child1, child2, 3); Node* nodePtr = &m_graph[m_compileIndex]; switch (nodePtr->arrayMode().modeForPut().type()) { - case Array::Double: - fixDoubleEdge(2); - break; case Array::Int8Array: case Array::Int16Array: case Array::Int32Array: @@ -382,19 +355,6 @@ private: break; } - case NewArray: { - for (unsigned i = m_graph.varArgNumChildren(node); i--;) { - node.setIndexingType( - leastUpperBoundOfIndexingTypeAndType( - node.indexingType(), m_graph[m_graph.varArgChild(node, i)].prediction())); - } - if (node.indexingType() == ArrayWithDouble) { - for (unsigned i = m_graph.varArgNumChildren(node); i--;) - fixDoubleEdge(i); - } - break; - } - default: break; } @@ -432,17 +392,15 @@ private: if (arrayMode.isJSArrayWithOriginalStructure()) { JSGlobalObject* globalObject = m_graph.baselineCodeBlockFor(codeOrigin)->globalObject(); switch (arrayMode.type()) { - case Array::Int32: - structure = globalObject->originalArrayStructureForIndexingType(ArrayWithInt32); - break; - case Array::Double: - structure = globalObject->originalArrayStructureForIndexingType(ArrayWithDouble); - break; case Array::Contiguous: - structure = globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous); + structure = globalObject->arrayStructure(); + if (structure->indexingType() != ArrayWithContiguous) + structure = 0; break; case Array::ArrayStorage: - structure = globalObject->originalArrayStructureForIndexingType(ArrayWithArrayStorage); + structure = globalObject->arrayStructureWithArrayStorage(); + if (structure->indexingType() != ArrayWithArrayStorage) + structure = 0; break; default: break; diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp index 38079f020..8e8817f81 100644 --- a/Source/JavaScriptCore/dfg/DFGGraph.cpp +++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp @@ -287,11 +287,6 @@ void Graph::dump(const char* prefix, NodeIndex nodeIndex) dataLog("]"); hasPrinted = true; } - if (node.hasIndexingType()) { - if (hasPrinted) - dataLog(", "); - dataLog("%s", indexingTypeToString(node.indexingType())); - } if (op == JSConstant) { dataLog("%s$%u", hasPrinted ? ", " : "", node.constantNumber()); JSValue value = valueOfJSConstant(nodeIndex); diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h index 4de2e0e26..9fbb2df07 100644 --- a/Source/JavaScriptCore/dfg/DFGGraph.h +++ b/Source/JavaScriptCore/dfg/DFGGraph.h @@ -220,7 +220,7 @@ public: if (right.hasConstant()) return addImmediateShouldSpeculateInteger(add, left, right); - return Node::shouldSpeculateIntegerExpectingDefined(left, right) && add.canSpeculateInteger(); + return Node::shouldSpeculateInteger(left, right) && add.canSpeculateInteger(); } bool mulShouldSpeculateInteger(Node& mul) @@ -235,13 +235,13 @@ public: if (right.hasConstant()) return mulImmediateShouldSpeculateInteger(mul, left, right); - return Node::shouldSpeculateIntegerForArithmetic(left, right) && mul.canSpeculateInteger() && !nodeMayOverflow(mul.arithNodeFlags()); + return Node::shouldSpeculateInteger(left, right) && mul.canSpeculateInteger() && !nodeMayOverflow(mul.arithNodeFlags()); } bool negateShouldSpeculateInteger(Node& negate) { ASSERT(negate.op() == ArithNegate); - return at(negate.child1()).shouldSpeculateIntegerForArithmetic() && negate.canSpeculateInteger(); + return at(negate.child1()).shouldSpeculateInteger() && negate.canSpeculateInteger(); } bool addShouldSpeculateInteger(NodeIndex nodeIndex) @@ -493,8 +493,6 @@ public: switch (node.arrayMode().type()) { case Array::Generic: return false; - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: return !node.arrayMode().isOutOfBounds(); @@ -714,7 +712,7 @@ private: if (!immediateValue.isNumber()) return false; - if (!variable.shouldSpeculateIntegerExpectingDefined()) + if (!variable.shouldSpeculateInteger()) return false; if (immediateValue.isInt32()) @@ -736,7 +734,7 @@ private: if (!immediateValue.isInt32()) return false; - if (!variable.shouldSpeculateIntegerForArithmetic()) + if (!variable.shouldSpeculateInteger()) return false; int32_t intImmediate = immediateValue.asInt32(); diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h index bff7fe65f..e66629ec4 100644 --- a/Source/JavaScriptCore/dfg/DFGNode.h +++ b/Source/JavaScriptCore/dfg/DFGNode.h @@ -62,7 +62,6 @@ struct StructureTransitionData { struct NewArrayBufferData { unsigned startConstant; unsigned numConstants; - IndexingType indexingType; }; // This type used in passing an immediate argument to Node constructor; @@ -434,32 +433,6 @@ struct Node { return newArrayBufferData()->numConstants; } - bool hasIndexingType() - { - switch (op()) { - case NewArray: - case NewArrayWithSize: - case NewArrayBuffer: - return true; - default: - return false; - } - } - - IndexingType indexingType() - { - ASSERT(hasIndexingType()); - if (op() == NewArrayBuffer) - return newArrayBufferData()->indexingType; - return m_opInfo; - } - - void setIndexingType(IndexingType indexingType) - { - ASSERT(hasIndexingType()); - m_opInfo = indexingType; - } - bool hasRegexpIndex() { return op() == NewRegexp; @@ -949,36 +922,16 @@ struct Node { return isInt32Speculation(prediction()); } - bool shouldSpeculateIntegerForArithmetic() - { - return isInt32SpeculationForArithmetic(prediction()); - } - - bool shouldSpeculateIntegerExpectingDefined() - { - return isInt32SpeculationExpectingDefined(prediction()); - } - bool shouldSpeculateDouble() { return isDoubleSpeculation(prediction()); } - bool shouldSpeculateDoubleForArithmetic() - { - return isDoubleSpeculationForArithmetic(prediction()); - } - bool shouldSpeculateNumber() { return isNumberSpeculation(prediction()); } - bool shouldSpeculateNumberExpectingDefined() - { - return isNumberSpeculationExpectingDefined(prediction()); - } - bool shouldSpeculateBoolean() { return isBooleanSpeculation(prediction()); @@ -1084,31 +1037,11 @@ struct Node { return op1.shouldSpeculateInteger() && op2.shouldSpeculateInteger(); } - static bool shouldSpeculateIntegerForArithmetic(Node& op1, Node& op2) - { - return op1.shouldSpeculateIntegerForArithmetic() && op2.shouldSpeculateIntegerForArithmetic(); - } - - static bool shouldSpeculateIntegerExpectingDefined(Node& op1, Node& op2) - { - return op1.shouldSpeculateIntegerExpectingDefined() && op2.shouldSpeculateIntegerExpectingDefined(); - } - - static bool shouldSpeculateDoubleForArithmetic(Node& op1, Node& op2) - { - return op1.shouldSpeculateDoubleForArithmetic() && op2.shouldSpeculateDoubleForArithmetic(); - } - static bool shouldSpeculateNumber(Node& op1, Node& op2) { return op1.shouldSpeculateNumber() && op2.shouldSpeculateNumber(); } - static bool shouldSpeculateNumberExpectingDefined(Node& op1, Node& op2) - { - return op1.shouldSpeculateNumberExpectingDefined() && op2.shouldSpeculateNumberExpectingDefined(); - } - static bool shouldSpeculateFinalObject(Node& op1, Node& op2) { return op1.shouldSpeculateFinalObject() && op2.shouldSpeculateFinalObject(); diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index 8356d22f9..0e45e230c 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -27,9 +27,9 @@ #include "DFGOperations.h" #include "Arguments.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" #include "CodeBlock.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "DFGOSRExit.h" #include "DFGRepatch.h" #include "DFGThunks.h" @@ -580,40 +580,6 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot); } -void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value) -{ - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); - - JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value); - - if (index >= 0) { - array->putByIndexInline(exec, index, jsValue, true); - return; - } - - PutPropertySlot slot(true); - array->methodTable()->put( - array, exec, Identifier::from(exec, index), jsValue, slot); -} - -void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value) -{ - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); - - JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value); - - if (index >= 0) { - array->putByIndexInline(exec, index, jsValue, false); - return; - } - - PutPropertySlot slot(false); - array->methodTable()->put( - array, exec, Identifier::from(exec, index), jsValue, slot); -} - EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array) { JSGlobalData* globalData = &exec->globalData(); @@ -623,15 +589,6 @@ EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue return JSValue::encode(jsNumber(array->length())); } -EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array) -{ - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); - - array->push(exec, JSValue(JSValue::EncodeAsDouble, value)); - return JSValue::encode(jsNumber(array->length())); -} - EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array) { JSGlobalData* globalData = &exec->globalData(); @@ -1370,36 +1327,30 @@ char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* return reinterpret_cast<char*>(result); } -char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSObject* object) +char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSObject* object) { JSGlobalData& globalData = exec->globalData(); NativeCallFrameTracer tracer(&globalData, exec); - return reinterpret_cast<char*>(object->ensureInt32(globalData)); + return reinterpret_cast<char*>(object->ensureContiguous(globalData)); } -char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSObject* object) +char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSObject* object) { JSGlobalData& globalData = exec->globalData(); NativeCallFrameTracer tracer(&globalData, exec); - - return reinterpret_cast<char*>(object->ensureDouble(globalData)); -} -char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSObject* object) -{ - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); - - return reinterpret_cast<char*>(object->ensureContiguous(globalData)); + return reinterpret_cast<char*>(object->ensureArrayStorage(globalData)); } -char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSObject* object) +char* DFG_OPERATION operationEnsureContiguousOrArrayStorage(ExecState* exec, JSObject* object, int32_t index) { JSGlobalData& globalData = exec->globalData(); NativeCallFrameTracer tracer(&globalData, exec); - return reinterpret_cast<char*>(object->ensureArrayStorage(globalData)); + if (static_cast<unsigned>(index) >= MIN_SPARSE_ARRAY_INDEX) + return reinterpret_cast<char*>(object->ensureArrayStorage(globalData)); + return reinterpret_cast<char*>(object->ensureIndexedStorage(globalData)); } double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b) diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h index b99c214e9..8d2beacec 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.h +++ b/Source/JavaScriptCore/dfg/DFGOperations.h @@ -64,7 +64,6 @@ typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EAZ)(ExecState*, JSArray*, typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECI)(ExecState*, JSCell*, Identifier*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue); -typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EDA)(ExecState*, double, JSArray*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EGriJsgI)(ExecState*, ResolveOperation*, JSGlobalObject*, Identifier*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EI)(ExecState*, Identifier*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EIRo)(ExecState*, Identifier*, ResolveOperations*); @@ -93,7 +92,6 @@ typedef size_t DFG_OPERATION (*S_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*) typedef size_t DFG_OPERATION (*S_DFGOperation_EJ)(ExecState*, EncodedJSValue); typedef size_t DFG_OPERATION (*S_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); typedef size_t DFG_OPERATION (*S_DFGOperation_J)(EncodedJSValue); -typedef void DFG_OPERATION (*V_DFGOperation_EOZD)(ExecState*, JSObject*, int32_t, double); typedef void DFG_OPERATION (*V_DFGOperation_EOZJ)(ExecState*, JSObject*, int32_t, EncodedJSValue); typedef void DFG_OPERATION (*V_DFGOperation_EC)(ExecState*, JSCell*); typedef void DFG_OPERATION (*V_DFGOperation_ECIcf)(ExecState*, JSCell*, InlineCallFrame*); @@ -150,10 +148,7 @@ void DFG_OPERATION operationPutByValCellStrict(ExecState*, JSCell*, EncodedJSVal void DFG_OPERATION operationPutByValCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL; void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL; void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL; -void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState*, JSObject*, int32_t index, double value) WTF_INTERNAL; -void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState*, JSObject*, int32_t index, double value) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*) WTF_INTERNAL; -EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState*, double value, JSArray*) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState*, JSArray*) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState*, JSCell*, JSCell*) WTF_INTERNAL; @@ -200,10 +195,9 @@ char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecStat char* DFG_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL; char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL; char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*, JSObject*, size_t newSize) WTF_INTERNAL; -char* DFG_OPERATION operationEnsureInt32(ExecState*, JSObject*); -char* DFG_OPERATION operationEnsureDouble(ExecState*, JSObject*); char* DFG_OPERATION operationEnsureContiguous(ExecState*, JSObject*); char* DFG_OPERATION operationEnsureArrayStorage(ExecState*, JSObject*); +char* DFG_OPERATION operationEnsureContiguousOrArrayStorage(ExecState*, JSObject*, int32_t); // This method is used to lookup an exception hander, keyed by faultLocation, which is // the return location from one of the calls out to one of the helper operations above. diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp index b5fde4eee..3e8ead5c6 100644 --- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp @@ -225,6 +225,24 @@ private: break; } + case ArithMod: { + SpeculatedType left = m_graph[node.child1()].prediction(); + SpeculatedType right = m_graph[node.child2()].prediction(); + + if (left && right) { + if (isInt32Speculation(mergeSpeculations(left, right)) + && nodeCanSpeculateInteger(node.arithNodeFlags())) + changed |= mergePrediction(SpecInt32); + else + changed |= mergePrediction(SpecDouble); + } + + flags |= NodeUsedAsValue; + changed |= m_graph[node.child1()].mergeFlags(flags); + changed |= m_graph[node.child2()].mergeFlags(flags); + break; + } + case UInt32ToNumber: { if (nodeCanSpeculateInteger(node.arithNodeFlags())) changed |= mergePrediction(SpecInt32); @@ -240,7 +258,7 @@ private: SpeculatedType right = m_graph[node.child2()].prediction(); if (left && right) { - if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) { + if (isNumberSpeculation(left) && isNumberSpeculation(right)) { if (m_graph.addShouldSpeculateInteger(node)) changed |= mergePrediction(SpecInt32); else @@ -315,7 +333,7 @@ private: SpeculatedType right = m_graph[node.child2()].prediction(); if (left && right) { - if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) + if (isInt32Speculation(mergeSpeculations(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) changed |= mergePrediction(SpecInt32); else @@ -355,7 +373,7 @@ private: SpeculatedType right = m_graph[node.child2()].prediction(); if (left && right) { - if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) + if (isInt32Speculation(mergeSpeculations(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) changed |= mergePrediction(SpecInt32); else @@ -364,7 +382,7 @@ private: // As soon as a multiply happens, we can easily end up in the part // of the double domain where the point at which you do truncation - // can change the outcome. So, ArithDiv always checks for overflow + // can change the outcome. So, ArithMul always checks for overflow // no matter what, and always forces its inputs to check as well. flags |= NodeUsedAsNumber | NodeNeedsNegZero; @@ -373,24 +391,6 @@ private: break; } - case ArithMod: { - SpeculatedType left = m_graph[node.child1()].prediction(); - SpeculatedType right = m_graph[node.child2()].prediction(); - - if (left && right) { - if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()]) - && nodeCanSpeculateInteger(node.arithNodeFlags())) - changed |= mergePrediction(SpecInt32); - else - changed |= mergePrediction(SpecDouble); - } - - flags |= NodeUsedAsValue; - changed |= m_graph[node.child1()].mergeFlags(flags); - changed |= m_graph[node.child2()].mergeFlags(flags); - break; - } - case ArithSqrt: { changed |= setPrediction(SpecDouble); changed |= m_graph[node.child1()].mergeFlags(flags | NodeUsedAsValue); @@ -399,11 +399,10 @@ private: case ArithAbs: { SpeculatedType child = m_graph[node.child1()].prediction(); - if (isInt32SpeculationForArithmetic(child) - && nodeCanSpeculateInteger(node.arithNodeFlags())) - changed |= mergePrediction(SpecInt32); + if (nodeCanSpeculateInteger(node.arithNodeFlags())) + changed |= mergePrediction(child); else - changed |= mergePrediction(speculatedDoubleTypeForPrediction(child)); + changed |= setPrediction(speculatedDoubleTypeForPrediction(child)); flags &= ~NodeNeedsNegZero; changed |= m_graph[node.child1()].mergeFlags(flags); @@ -777,7 +776,7 @@ private: DoubleBallot ballot; - if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right) + if (isNumberSpeculation(left) && isNumberSpeculation(right) && !m_graph.addShouldSpeculateInteger(node)) ballot = VoteDouble; else @@ -815,7 +814,7 @@ private: DoubleBallot ballot; if (isNumberSpeculation(left) && isNumberSpeculation(right) - && !(Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child1()]) + && !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()]) && node.canSpeculateInteger())) ballot = VoteDouble; else @@ -828,7 +827,7 @@ private: case ArithAbs: DoubleBallot ballot; - if (!(m_graph[node.child1()].shouldSpeculateIntegerForArithmetic() + if (!(m_graph[node.child1()].shouldSpeculateInteger() && node.canSpeculateInteger())) ballot = VoteDouble; else @@ -850,24 +849,6 @@ private: break; } - case PutByVal: - case PutByValAlias: { - Edge child1 = m_graph.varArgChild(node, 0); - Edge child2 = m_graph.varArgChild(node, 1); - Edge child3 = m_graph.varArgChild(node, 2); - m_graph.vote(child1, VoteValue); - m_graph.vote(child2, VoteValue); - switch (node.arrayMode().type()) { - case Array::Double: - m_graph.vote(child3, VoteDouble); - break; - default: - m_graph.vote(child3, VoteValue); - break; - } - break; - } - default: m_graph.vote(node, VoteValue); break; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index 829bc14ff..6bedd6d68 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -59,7 +59,7 @@ SpeculativeJIT::~SpeculativeJIT() void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR, GPRReg storageGPR, unsigned numElements) { - ASSERT(hasUndecided(structure->indexingType()) || hasInt32(structure->indexingType()) || hasDouble(structure->indexingType()) || hasContiguous(structure->indexingType())); + ASSERT(hasContiguous(structure->indexingType())); GPRTemporary scratch(this); GPRReg scratchGPR = scratch.gpr(); @@ -67,7 +67,6 @@ void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR, unsigned vectorLength = std::max(BASE_VECTOR_LEN, numElements); JITCompiler::JumpList slowCases; - slowCases.append( emitAllocateBasicStorage(TrustedImm32(vectorLength * sizeof(JSValue) + sizeof(IndexingHeader)), storageGPR)); m_jit.subPtr(TrustedImm32(vectorLength * sizeof(JSValue)), storageGPR); @@ -80,21 +79,6 @@ void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR, m_jit.store32(TrustedImm32(numElements), MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); m_jit.store32(TrustedImm32(vectorLength), MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); - if (hasDouble(structure->indexingType()) && numElements < vectorLength) { -#if USE(JSVALUE64) - m_jit.move(TrustedImm64(bitwise_cast<int64_t>(QNaN)), scratchGPR); - for (unsigned i = numElements; i < vectorLength; ++i) - m_jit.store64(scratchGPR, MacroAssembler::Address(storageGPR, sizeof(double) * i)); -#else - EncodedValueDescriptor value; - value.asInt64 = JSValue::encode(JSValue(JSValue::EncodeAsDouble, QNaN)); - for (unsigned i = numElements; i < vectorLength; ++i) { - m_jit.store32(TrustedImm32(value.asBits.tag), MacroAssembler::Address(storageGPR, sizeof(double) * i + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(TrustedImm32(value.asBits.payload), MacroAssembler::Address(storageGPR, sizeof(double) * i + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - } -#endif - } - // I want a slow path that also loads out the storage pointer, and that's // what this custom CallArrayAllocatorSlowPathGenerator gives me. It's a lot // of work for a very small piece of functionality. :-/ @@ -359,31 +343,24 @@ const TypedArrayDescriptor* SpeculativeJIT::typedArrayDescriptor(ArrayMode array } } -JITCompiler::Jump SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, ArrayMode arrayMode, IndexingType shape, bool invert) -{ - if (arrayMode.isJSArray()) { - m_jit.and32(TrustedImm32(IsArray | IndexingShapeMask), tempGPR); - return m_jit.branch32( - invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(IsArray | shape)); - } - m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR); - return m_jit.branch32(invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(shape)); -} - JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, ArrayMode arrayMode, bool invert) { JITCompiler::JumpList result; switch (arrayMode.type()) { - case Array::Int32: - return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, Int32Shape, invert); - - case Array::Double: - return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, DoubleShape, invert); - - case Array::Contiguous: - return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, ContiguousShape, invert); - + case Array::Contiguous: { + if (arrayMode.isJSArray()) { + m_jit.and32(TrustedImm32(IsArray | IndexingShapeMask), tempGPR); + result.append( + m_jit.branch32( + invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(IsArray | ContiguousShape))); + break; + } + m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR); + result.append( + m_jit.branch32(invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(ContiguousShape))); + break; + } case Array::ArrayStorage: case Array::SlowPutArrayStorage: { if (arrayMode.isJSArray()) { @@ -460,8 +437,6 @@ void SpeculativeJIT::checkArray(Node& node) case Array::String: expectedClassInfo = &JSString::s_info; break; - case Array::Int32: - case Array::Double: case Array::Contiguous: case Array::ArrayStorage: case Array::SlowPutArrayStorage: { @@ -553,30 +528,16 @@ void SpeculativeJIT::arrayify(Node& node, GPRReg baseReg, GPRReg propertyReg) // If we're allegedly creating contiguous storage and the index is bogus, then // just don't. - if (propertyReg != InvalidGPRReg) { - switch (node.arrayMode().type()) { - case Array::Int32: - case Array::Double: - case Array::Contiguous: - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branch32( - MacroAssembler::AboveOrEqual, propertyReg, TrustedImm32(MIN_SPARSE_ARRAY_INDEX))); - break; - default: - break; - } + if (node.arrayMode().type() == Array::Contiguous && propertyReg != InvalidGPRReg) { + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branch32( + MacroAssembler::AboveOrEqual, propertyReg, TrustedImm32(MIN_SPARSE_ARRAY_INDEX))); } // Now call out to create the array storage. silentSpillAllRegisters(tempGPR); switch (node.arrayMode().type()) { - case Array::Int32: - callOperation(operationEnsureInt32, tempGPR, baseReg); - break; - case Array::Double: - callOperation(operationEnsureDouble, tempGPR, baseReg); - break; case Array::Contiguous: callOperation(operationEnsureContiguous, tempGPR, baseReg); break; @@ -1836,85 +1797,6 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo return ValueRecovery(); } -void SpeculativeJIT::compileDoublePutByVal(Node& node, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property) -{ - Edge child3 = m_jit.graph().varArgChild(node, 2); - Edge child4 = m_jit.graph().varArgChild(node, 3); - - ArrayMode arrayMode = node.arrayMode(); - - GPRReg baseReg = base.gpr(); - GPRReg propertyReg = property.gpr(); - - SpeculateDoubleOperand value(this, child3); - - FPRReg valueReg = value.fpr(); - - if (!isRealNumberSpeculation(m_state.forNode(child3).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg)); - } - - if (!m_compileOkay) - return; - - StorageOperand storage(this, child4); - GPRReg storageReg = storage.gpr(); - - if (node.op() == PutByValAlias) { - // Store the value to the array. - GPRReg propertyReg = property.gpr(); - FPRReg valueReg = value.fpr(); - m_jit.storeDouble(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight)); - - noResult(m_compileIndex); - return; - } - - GPRTemporary temporary; - GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node); - - MacroAssembler::JumpList slowCases; - - if (arrayMode.isInBounds()) { - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - } else { - MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); - - slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()))); - - if (!arrayMode.isOutOfBounds()) - speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases); - - m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg); - m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); - - inBounds.link(&m_jit); - } - - m_jit.storeDouble(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight)); - - base.use(); - property.use(); - value.use(); - storage.use(); - - if (arrayMode.isOutOfBounds()) { - addSlowPathGenerator( - slowPathCall( - slowCases, this, - m_jit.codeBlock()->isStrictMode() ? operationPutDoubleByValBeyondArrayBoundsStrict : operationPutDoubleByValBeyondArrayBoundsNonStrict, - NoResult, baseReg, propertyReg, valueReg)); - } - - noResult(m_compileIndex, UseChildrenCalledExplicitly); -} - void SpeculativeJIT::compileGetCharCodeAt(Node& node) { SpeculateCellOperand string(this, node.child1()); @@ -2881,7 +2763,7 @@ void SpeculativeJIT::compileAdd(Node& node) return; } - if (Node::shouldSpeculateNumberExpectingDefined(at(node.child1()), at(node.child2()))) { + if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) { SpeculateDoubleOperand op1(this, node.child1()); SpeculateDoubleOperand op2(this, node.child2()); FPRTemporary result(this, op1, op2); @@ -3119,7 +3001,7 @@ void SpeculativeJIT::compileIntegerArithDivForX86(Node& node) void SpeculativeJIT::compileArithMod(Node& node) { - if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2())) + if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) { compileSoftModulo(node); return; @@ -3454,8 +3336,6 @@ void SpeculativeJIT::compileGetArrayLength(Node& node) const TypedArrayDescriptor* descriptor = typedArrayDescriptor(node.arrayMode()); switch (node.arrayMode().type()) { - case Array::Int32: - case Array::Double: case Array::Contiguous: { StorageOperand storage(this, node.child2()); GPRTemporary result(this, storage); diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h index 059d3a6c6..446ea7dbe 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h @@ -1308,11 +1308,6 @@ public: m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier)); return appendCallWithExceptionCheckSetResult(operation, result); } - JITCompiler::Call callOperation(J_DFGOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2) - { - m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, result); - } JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2) { m_jit.setupArgumentsWithExecState(arg1, arg2); @@ -1458,11 +1453,6 @@ public: m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); return appendCallWithExceptionCheck(operation); } - JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3) - { - m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); - } JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) { m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); @@ -1671,21 +1661,11 @@ public: m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(identifier)); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } - JITCompiler::Call callOperation(J_DFGOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2) - { - m_jit.setupArgumentsWithExecState(arg1, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); - } JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) { m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } - JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2) - { - m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); - } JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload) { m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); @@ -1839,21 +1819,11 @@ public: m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); return appendCallWithExceptionCheck(operation); } - JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3) - { - m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); - return appendCallWithExceptionCheck(operation); - } JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) { m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); return appendCallWithExceptionCheck(operation); } - JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload) - { - m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); - return appendCallWithExceptionCheck(operation); - } JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet) { m_jit.setupArguments(TrustedImmPtr(watchpointSet)); @@ -2300,11 +2270,6 @@ public: void compileAllocatePropertyStorage(Node&); void compileReallocatePropertyStorage(Node&); -#if USE(JSVALUE32_64) - template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType> - void compileContiguousPutByVal(Node&, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag); -#endif - void compileDoublePutByVal(Node&, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property); bool putByValWillNeedExtraRegister(ArrayMode arrayMode) { return arrayMode.mayStoreToHole(); @@ -2450,7 +2415,6 @@ public: const TypedArrayDescriptor* typedArrayDescriptor(ArrayMode); - JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType, bool invert); JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, bool invert = false); void checkArray(Node&); void arrayify(Node&, GPRReg baseReg, GPRReg propertyReg); @@ -2991,11 +2955,6 @@ public: m_gprOrInvalid = m_jit->fillSpeculateInt(index(), m_format); return m_gprOrInvalid; } - - void use() - { - m_jit->use(m_index); - } private: SpeculativeJIT* m_jit; @@ -3076,11 +3035,6 @@ public: m_fprOrInvalid = m_jit->fillSpeculateDouble(index()); return m_fprOrInvalid; } - - void use() - { - m_jit->use(m_index); - } private: SpeculativeJIT* m_jit; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp index 694f1452e..65fdf5593 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp @@ -2046,69 +2046,6 @@ void SpeculativeJIT::emitBranch(Node& node) } } -template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType> -void SpeculativeJIT::compileContiguousPutByVal(Node& node, BaseOperandType& base, PropertyOperandType& property, ValueOperandType& value, GPRReg valuePayloadReg, TagType valueTag) -{ - Edge child4 = m_jit.graph().varArgChild(node, 3); - - ArrayMode arrayMode = node.arrayMode(); - - GPRReg baseReg = base.gpr(); - GPRReg propertyReg = property.gpr(); - - StorageOperand storage(this, child4); - GPRReg storageReg = storage.gpr(); - - if (node.op() == PutByValAlias) { - // Store the value to the array. - GPRReg propertyReg = property.gpr(); - m_jit.store32(valueTag, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - - noResult(m_compileIndex); - return; - } - - MacroAssembler::JumpList slowCases; - - if (arrayMode.isInBounds()) { - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - } else { - MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); - - slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()))); - - if (!arrayMode.isOutOfBounds()) - speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases); - - m_jit.add32(TrustedImm32(1), propertyReg); - m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); - m_jit.sub32(TrustedImm32(1), propertyReg); - - inBounds.link(&m_jit); - } - - m_jit.store32(valueTag, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - - base.use(); - property.use(); - value.use(); - storage.use(); - - if (arrayMode.isOutOfBounds()) { - addSlowPathGenerator( - slowPathCall( - slowCases, this, - m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, - NoResult, baseReg, propertyReg, valueTag, valuePayloadReg)); - } - - noResult(m_compileIndex, UseChildrenCalledExplicitly); -} - void SpeculativeJIT::compile(Node& node) { NodeType op = node.op(); @@ -2429,8 +2366,7 @@ void SpeculativeJIT::compile(Node& node) break; case ArithDiv: { - if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2())) - && node.canSpeculateInteger()) { + if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) { #if CPU(X86) compileIntegerArithDivForX86(node); #else // CPU(X86) -> so non-X86 code follows @@ -2457,8 +2393,7 @@ void SpeculativeJIT::compile(Node& node) } case ArithAbs: { - if (at(node.child1()).shouldSpeculateIntegerForArithmetic() - && node.canSpeculateInteger()) { + if (at(node.child1()).shouldSpeculateInteger() && node.canSpeculateInteger()) { SpeculateIntegerOperand op1(this, node.child1()); GPRTemporary result(this, op1); GPRTemporary scratch(this); @@ -2482,8 +2417,7 @@ void SpeculativeJIT::compile(Node& node) case ArithMin: case ArithMax: { - if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2())) - && node.canSpeculateInteger()) { + if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) { SpeculateStrictInt32Operand op1(this, node.child1()); SpeculateStrictInt32Operand op2(this, node.child2()); GPRTemporary result(this, op1); @@ -2633,7 +2567,6 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); break; } - case Array::Int32: case Array::Contiguous: { if (node.arrayMode().isInBounds()) { SpeculateStrictInt32Operand property(this, node.child2()); @@ -2647,20 +2580,8 @@ void SpeculativeJIT::compile(Node& node) speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - GPRTemporary resultPayload(this); - if (node.arrayMode().type() == Array::Int32) { - speculationCheck( - OutOfBounds, JSValueRegs(), NoNode, - m_jit.branch32( - MacroAssembler::Equal, - MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), - TrustedImm32(JSValue::EmptyValueTag))); - m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr()); - integerResult(resultPayload.gpr(), m_compileIndex); - break; - } - GPRTemporary resultTag(this); + GPRTemporary resultPayload(this); m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr()); speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag))); m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr()); @@ -2700,60 +2621,6 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex); break; } - case Array::Double: { - if (node.arrayMode().isInBounds()) { - SpeculateStrictInt32Operand property(this, node.child2()); - StorageOperand storage(this, node.child3()); - - GPRReg propertyReg = property.gpr(); - GPRReg storageReg = storage.gpr(); - - if (!m_compileOkay) - return; - - speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - - FPRTemporary result(this); - m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr()); - speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr())); - doubleResult(result.fpr(), m_compileIndex); - break; - } - - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - StorageOperand storage(this, node.child3()); - - GPRReg baseReg = base.gpr(); - GPRReg propertyReg = property.gpr(); - GPRReg storageReg = storage.gpr(); - - if (!m_compileOkay) - return; - - GPRTemporary resultTag(this); - GPRTemporary resultPayload(this); - FPRTemporary temp(this); - GPRReg resultTagReg = resultTag.gpr(); - GPRReg resultPayloadReg = resultPayload.gpr(); - FPRReg tempReg = temp.fpr(); - - MacroAssembler::JumpList slowCases; - - slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - - m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), tempReg); - slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempReg, tempReg)); - boxDouble(tempReg, resultTagReg, resultPayloadReg); - - addSlowPathGenerator( - slowPathCall( - slowCases, this, operationGetByValArrayInt, - JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg)); - - jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex); - break; - } case Array::ArrayStorage: case Array::SlowPutArrayStorage: { if (node.arrayMode().isInBounds()) { @@ -2904,17 +2771,6 @@ void SpeculativeJIT::compile(Node& node) GPRReg propertyReg = property.gpr(); switch (arrayMode.type()) { - case Array::Int32: { - SpeculateIntegerOperand value(this, child3); - - GPRReg valuePayloadReg = value.gpr(); - - if (!m_compileOkay) - return; - - compileContiguousPutByVal(node, base, property, value, valuePayloadReg, TrustedImm32(JSValue::Int32Tag)); - break; - } case Array::Contiguous: { JSValueOperand value(this, child3); @@ -2928,14 +2784,61 @@ void SpeculativeJIT::compile(Node& node) GPRTemporary scratch(this); writeBarrier(baseReg, valueTagReg, child3, WriteBarrierForPropertyAccess, scratch.gpr()); } + + StorageOperand storage(this, child4); + GPRReg storageReg = storage.gpr(); + + if (node.op() == PutByValAlias) { + // Store the value to the array. + GPRReg propertyReg = property.gpr(); + m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + + noResult(m_compileIndex); + break; + } - compileContiguousPutByVal(node, base, property, value, valuePayloadReg, valueTagReg); - break; - } - case Array::Double: { - compileDoublePutByVal(node, base, property); + MacroAssembler::JumpList slowCases; + + if (arrayMode.isInBounds()) { + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + } else { + MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); + + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()))); + + if (!arrayMode.isOutOfBounds()) + speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases); + + m_jit.add32(TrustedImm32(1), propertyReg); + m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); + m_jit.sub32(TrustedImm32(1), propertyReg); + + inBounds.link(&m_jit); + } + + m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + + base.use(); + property.use(); + value.use(); + storage.use(); + + if (arrayMode.isOutOfBounds()) { + addSlowPathGenerator( + slowPathCall( + slowCases, this, + m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, + NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg)); + } + + noResult(m_compileIndex, UseChildrenCalledExplicitly); break; } + case Array::ArrayStorage: case Array::SlowPutArrayStorage: { JSValueOperand value(this, child3); @@ -3125,47 +3028,24 @@ void SpeculativeJIT::compile(Node& node) ASSERT(node.arrayMode().isJSArray()); SpeculateCellOperand base(this, node.child1()); + JSValueOperand value(this, node.child2()); GPRTemporary storageLength(this); GPRReg baseGPR = base.gpr(); + GPRReg valueTagGPR = value.tagGPR(); + GPRReg valuePayloadGPR = value.payloadGPR(); GPRReg storageLengthGPR = storageLength.gpr(); + if (Heap::isWriteBarrierEnabled()) { + GPRTemporary scratch(this); + writeBarrier(baseGPR, valueTagGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR); + } + StorageOperand storage(this, node.child3()); GPRReg storageGPR = storage.gpr(); switch (node.arrayMode().type()) { - case Array::Int32: { - SpeculateIntegerOperand value(this, node.child2()); - GPRReg valuePayloadGPR = value.gpr(); - - m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); - MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); - m_jit.store32(TrustedImm32(JSValue::Int32Tag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - m_jit.add32(TrustedImm32(1), storageLengthGPR); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); - m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR); - - addSlowPathGenerator( - slowPathCall( - slowPath, this, operationArrayPush, - JSValueRegs(storageGPR, storageLengthGPR), - TrustedImm32(JSValue::Int32Tag), valuePayloadGPR, baseGPR)); - - jsValueResult(storageGPR, storageLengthGPR, m_compileIndex); - break; - } - case Array::Contiguous: { - JSValueOperand value(this, node.child2()); - GPRReg valueTagGPR = value.tagGPR(); - GPRReg valuePayloadGPR = value.payloadGPR(); - - if (Heap::isWriteBarrierEnabled()) { - GPRTemporary scratch(this); - writeBarrier(baseGPR, valueTagGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR); - } - m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); @@ -3184,45 +3064,7 @@ void SpeculativeJIT::compile(Node& node) break; } - case Array::Double: { - SpeculateDoubleOperand value(this, node.child2()); - FPRReg valueFPR = value.fpr(); - - if (!isRealNumberSpeculation(m_state.forNode(node.child2()).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR)); - } - - m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); - MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); - m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight)); - m_jit.add32(TrustedImm32(1), storageLengthGPR); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); - m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR); - - addSlowPathGenerator( - slowPathCall( - slowPath, this, operationArrayPushDouble, - JSValueRegs(storageGPR, storageLengthGPR), - valueFPR, baseGPR)); - - jsValueResult(storageGPR, storageLengthGPR, m_compileIndex); - break; - } - case Array::ArrayStorage: { - JSValueOperand value(this, node.child2()); - GPRReg valueTagGPR = value.tagGPR(); - GPRReg valuePayloadGPR = value.payloadGPR(); - - if (Heap::isWriteBarrierEnabled()) { - GPRTemporary scratch(this); - writeBarrier(baseGPR, valueTagGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR); - } - m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); // Refuse to handle bizarre lengths. @@ -3265,7 +3107,6 @@ void SpeculativeJIT::compile(Node& node) GPRReg storageGPR = storage.gpr(); switch (node.arrayMode().type()) { - case Array::Int32: case Array::Contiguous: { m_jit.load32( MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), valuePayloadGPR); @@ -3299,44 +3140,6 @@ void SpeculativeJIT::compile(Node& node) break; } - case Array::Double: { - FPRTemporary temp(this); - FPRReg tempFPR = temp.fpr(); - - m_jit.load32( - MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), valuePayloadGPR); - MacroAssembler::Jump undefinedCase = - m_jit.branchTest32(MacroAssembler::Zero, valuePayloadGPR); - m_jit.sub32(TrustedImm32(1), valuePayloadGPR); - m_jit.store32( - valuePayloadGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); - m_jit.loadDouble( - MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight), - tempFPR); - MacroAssembler::Jump slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR); - JSValue nan = JSValue(JSValue::EncodeAsDouble, QNaN); - m_jit.store32( - MacroAssembler::TrustedImm32(nan.u.asBits.tag), - MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32( - MacroAssembler::TrustedImm32(nan.u.asBits.payload), - MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - boxDouble(tempFPR, valueTagGPR, valuePayloadGPR); - - addSlowPathGenerator( - slowPathMove( - undefinedCase, this, - MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR, - MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR)); - addSlowPathGenerator( - slowPathCall( - slowCase, this, operationArrayPopAndRecoverLength, - JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR)); - - jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex); - break; - } - case Array::ArrayStorage: { GPRTemporary storageLength(this); GPRReg storageLengthGPR = storageLength.gpr(); @@ -3555,17 +3358,11 @@ void SpeculativeJIT::compile(Node& node) case NewArray: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) { + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); - Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()); - ASSERT(structure->indexingType() == node.indexingType()); - ASSERT( - hasUndecided(structure->indexingType()) - || hasInt32(structure->indexingType()) - || hasDouble(structure->indexingType()) - || hasContiguous(structure->indexingType())); - + ASSERT(hasContiguous(globalObject->arrayStructure()->indexingType())); + unsigned numElements = node.numChildren(); GPRTemporary result(this); @@ -3574,52 +3371,17 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); GPRReg storageGPR = storage.gpr(); - emitAllocateJSArray(structure, resultGPR, storageGPR, numElements); + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); // At this point, one way or another, resultGPR and storageGPR have pointers to // the JSArray and the Butterfly, respectively. - ASSERT(!hasUndecided(structure->indexingType()) || !node.numChildren()); - for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { - Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]; - switch (node.indexingType()) { - case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - CRASH(); - break; - case ALL_DOUBLE_INDEXING_TYPES: { - SpeculateDoubleOperand operand(this, use); - FPRReg opFPR = operand.fpr(); - if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); - } - - m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx)); - break; - } - case ALL_INT32_INDEXING_TYPES: { - SpeculateIntegerOperand operand(this, use); - m_jit.store32(TrustedImm32(JSValue::Int32Tag), MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(operand.gpr(), MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - break; - } - case ALL_CONTIGUOUS_INDEXING_TYPES: { - JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); - GPRReg opTagGPR = operand.tagGPR(); - GPRReg opPayloadGPR = operand.payloadGPR(); - m_jit.store32(opTagGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(opPayloadGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - break; - } - default: - CRASH(); - break; - } + JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); + GPRReg opTagGPR = operand.tagGPR(); + GPRReg opPayloadGPR = operand.payloadGPR(); + m_jit.store32(opTagGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(opPayloadGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); } // Yuck, we should *really* have a way of also returning the storageGPR. But @@ -3637,7 +3399,7 @@ void SpeculativeJIT::compile(Node& node) flushRegisters(); GPRResult result(this); callOperation( - operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())); + operationNewEmptyArray, result.gpr(), globalObject->arrayStructure()); cellResult(result.gpr(), m_compileIndex); break; } @@ -3647,61 +3409,13 @@ void SpeculativeJIT::compile(Node& node) EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0; for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { - // Need to perform the speculations that this node promises to perform. If we're - // emitting code here and the indexing type is not array storage then there is - // probably something hilarious going on and we're already failing at all the - // things, but at least we're going to be sound. - Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]; - switch (node.indexingType()) { - case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - CRASH(); - break; - case ALL_DOUBLE_INDEXING_TYPES: { - SpeculateDoubleOperand operand(this, use); - FPRReg opFPR = operand.fpr(); - if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); - } - - m_jit.storeDouble(opFPR, reinterpret_cast<char*>(buffer + operandIdx)); - break; - } - case ALL_INT32_INDEXING_TYPES: { - SpeculateIntegerOperand operand(this, use); - GPRReg opGPR = operand.gpr(); - m_jit.store32(TrustedImm32(JSValue::Int32Tag), reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); - m_jit.store32(opGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); - break; - } - case ALL_CONTIGUOUS_INDEXING_TYPES: - case ALL_ARRAY_STORAGE_INDEXING_TYPES: { - JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); - GPRReg opTagGPR = operand.tagGPR(); - GPRReg opPayloadGPR = operand.payloadGPR(); - - m_jit.store32(opTagGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); - m_jit.store32(opPayloadGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); - operand.use(); - break; - } - default: - CRASH(); - break; - } - } - - switch (node.indexingType()) { - case ALL_DOUBLE_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - useChildren(node); - break; - default: - break; + JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); + GPRReg opTagGPR = operand.tagGPR(); + GPRReg opPayloadGPR = operand.payloadGPR(); + operand.use(); + + m_jit.store32(opTagGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); + m_jit.store32(opPayloadGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); } flushRegisters(); @@ -3717,8 +3431,8 @@ void SpeculativeJIT::compile(Node& node) GPRResult result(this); callOperation( - operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), - static_cast<void*>(buffer), node.numChildren()); + operationNewArray, result.gpr(), globalObject->arrayStructure(), + static_cast<void *>(buffer), node.numChildren()); if (scratchSize) { GPRTemporary scratch(this); @@ -3757,30 +3471,17 @@ void SpeculativeJIT::compile(Node& node) emitAllocateBasicStorage(resultGPR, storageGPR)); m_jit.subPtr(scratchGPR, storageGPR); emitAllocateBasicJSObject<JSArray, MarkedBlock::None>( - TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), resultGPR, scratchGPR, + TrustedImmPtr(globalObject->arrayStructure()), resultGPR, scratchGPR, storageGPR, sizeof(JSArray), slowCases); m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); - if (hasDouble(node.indexingType())) { - JSValue nan = JSValue(JSValue::EncodeAsDouble, QNaN); - - m_jit.move(sizeGPR, scratchGPR); - MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratchGPR); - MacroAssembler::Label loop = m_jit.label(); - m_jit.sub32(TrustedImm32(1), scratchGPR); - m_jit.store32(TrustedImm32(nan.u.asBits.tag), MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(TrustedImm32(nan.u.asBits.payload), MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit); - done.link(&m_jit); - } - addSlowPathGenerator(adoptPtr( new CallArrayAllocatorWithVariableSizeSlowPathGenerator( slowCases, this, operationNewArrayWithSize, resultGPR, - globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), - globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage), + globalObject->arrayStructure(), + globalObject->arrayStructureWithArrayStorage(), sizeGPR))); cellResult(resultGPR, m_compileIndex); @@ -3791,24 +3492,15 @@ void SpeculativeJIT::compile(Node& node) GPRReg sizeGPR = size.gpr(); flushRegisters(); GPRResult result(this); - GPRReg resultGPR = result.gpr(); - GPRReg structureGPR = selectScratchGPR(sizeGPR); - MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)); - m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), structureGPR); - MacroAssembler::Jump done = m_jit.jump(); - bigLength.link(&m_jit); - m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR); - done.link(&m_jit); callOperation( - operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR); - cellResult(resultGPR, m_compileIndex); + operationNewArrayWithSize, result.gpr(), globalObject->arrayStructure(), sizeGPR); + cellResult(result.gpr(), m_compileIndex); break; } case NewArrayBuffer: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - IndexingType indexingType = node.indexingType(); - if (!globalObject->isHavingABadTime() && !hasArrayStorage(indexingType)) { + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); unsigned numElements = node.numConstants(); @@ -3819,25 +3511,12 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); GPRReg storageGPR = storage.gpr(); - emitAllocateJSArray(globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), resultGPR, storageGPR, numElements); + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); - if (node.indexingType() == ArrayWithDouble) { - JSValue* data = m_jit.codeBlock()->constantBuffer(node.startConstant()); - for (unsigned index = 0; index < node.numConstants(); ++index) { - union { - int32_t halves[2]; - double value; - } u; - u.value = data[index].asNumber(); - m_jit.store32(Imm32(u.halves[0]), MacroAssembler::Address(storageGPR, sizeof(double) * index)); - m_jit.store32(Imm32(u.halves[1]), MacroAssembler::Address(storageGPR, sizeof(double) * index + sizeof(int32_t))); - } - } else { - int32_t* data = bitwise_cast<int32_t*>(m_jit.codeBlock()->constantBuffer(node.startConstant())); - for (unsigned index = 0; index < node.numConstants() * 2; ++index) { - m_jit.store32( - Imm32(data[index]), MacroAssembler::Address(storageGPR, sizeof(int32_t) * index)); - } + int32_t* data = bitwise_cast<int32_t*>(m_jit.codeBlock()->constantBuffer(node.startConstant())); + for (unsigned index = 0; index < node.numConstants() * 2; ++index) { + m_jit.store32( + Imm32(data[index]), MacroAssembler::Address(storageGPR, sizeof(int32_t) * index)); } cellResult(resultGPR, m_compileIndex); @@ -3847,7 +3526,7 @@ void SpeculativeJIT::compile(Node& node) flushRegisters(); GPRResult result(this); - callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), node.startConstant(), node.numConstants()); + callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructure(), node.startConstant(), node.numConstants()); cellResult(result.gpr(), m_compileIndex); break; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp index ecd823e7b..6c066c388 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp @@ -2403,8 +2403,7 @@ void SpeculativeJIT::compile(Node& node) break; case ArithDiv: { - if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2())) - && node.canSpeculateInteger()) { + if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) { compileIntegerArithDivForX86(node); break; } @@ -2427,8 +2426,7 @@ void SpeculativeJIT::compile(Node& node) } case ArithAbs: { - if (at(node.child1()).shouldSpeculateIntegerForArithmetic() - && node.canSpeculateInteger()) { + if (at(node.child1()).shouldSpeculateInteger() && node.canSpeculateInteger()) { SpeculateIntegerOperand op1(this, node.child1()); GPRTemporary result(this); GPRTemporary scratch(this); @@ -2452,8 +2450,7 @@ void SpeculativeJIT::compile(Node& node) case ArithMin: case ArithMax: { - if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2())) - && node.canSpeculateInteger()) { + if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) { SpeculateStrictInt32Operand op1(this, node.child1()); SpeculateStrictInt32Operand op2(this, node.child2()); GPRTemporary result(this, op1); @@ -2601,7 +2598,6 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(result.gpr(), m_compileIndex); break; } - case Array::Int32: case Array::Contiguous: { if (node.arrayMode().isInBounds()) { SpeculateStrictInt32Operand property(this, node.child2()); @@ -2618,7 +2614,7 @@ void SpeculativeJIT::compile(Node& node) GPRTemporary result(this); m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.gpr()); speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchTest64(MacroAssembler::Zero, result.gpr())); - jsValueResult(result.gpr(), m_compileIndex, node.arrayMode().type() == Array::Int32 ? DataFormatJSInteger : DataFormatJS); + jsValueResult(result.gpr(), m_compileIndex); break; } @@ -2651,60 +2647,6 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(resultReg, m_compileIndex); break; } - - case Array::Double: { - if (node.arrayMode().isInBounds()) { - SpeculateStrictInt32Operand property(this, node.child2()); - StorageOperand storage(this, node.child3()); - - GPRReg propertyReg = property.gpr(); - GPRReg storageReg = storage.gpr(); - - if (!m_compileOkay) - return; - - speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - - FPRTemporary result(this); - m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr()); - speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr())); - doubleResult(result.fpr(), m_compileIndex); - break; - } - - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - StorageOperand storage(this, node.child3()); - - GPRReg baseReg = base.gpr(); - GPRReg propertyReg = property.gpr(); - GPRReg storageReg = storage.gpr(); - - if (!m_compileOkay) - return; - - GPRTemporary result(this); - FPRTemporary temp(this); - GPRReg resultReg = result.gpr(); - FPRReg tempReg = temp.fpr(); - - MacroAssembler::JumpList slowCases; - - slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); - - m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), tempReg); - slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempReg, tempReg)); - boxDouble(tempReg, resultReg); - - addSlowPathGenerator( - slowPathCall( - slowCases, this, operationGetByValArrayInt, - result.gpr(), baseReg, propertyReg)); - - jsValueResult(resultReg, m_compileIndex); - break; - } - case Array::ArrayStorage: case Array::SlowPutArrayStorage: { if (node.arrayMode().isInBounds()) { @@ -2847,7 +2789,6 @@ void SpeculativeJIT::compile(Node& node) GPRReg propertyReg = property.gpr(); switch (arrayMode.type()) { - case Array::Int32: case Array::Contiguous: { JSValueOperand value(this, child3); @@ -2855,15 +2796,8 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - - if (arrayMode.type() == Array::Int32 - && !isInt32Speculation(m_state.forNode(child3).m_type)) { - speculationCheck( - BadType, JSValueRegs(valueReg), child3, - m_jit.branch64(MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister)); - } - if (arrayMode.type() == Array::Contiguous && Heap::isWriteBarrierEnabled()) { + if (Heap::isWriteBarrierEnabled()) { GPRTemporary scratch(this); writeBarrier(baseReg, value.gpr(), child3, WriteBarrierForPropertyAccess, scratch.gpr()); } @@ -2923,11 +2857,6 @@ void SpeculativeJIT::compile(Node& node) break; } - case Array::Double: { - compileDoublePutByVal(node, base, property); - break; - } - case Array::ArrayStorage: case Array::SlowPutArrayStorage: { JSValueOperand value(this, child3); @@ -3152,31 +3081,23 @@ void SpeculativeJIT::compile(Node& node) ASSERT(node.arrayMode().isJSArray()); SpeculateCellOperand base(this, node.child1()); + JSValueOperand value(this, node.child2()); GPRTemporary storageLength(this); GPRReg baseGPR = base.gpr(); + GPRReg valueGPR = value.gpr(); GPRReg storageLengthGPR = storageLength.gpr(); + if (Heap::isWriteBarrierEnabled()) { + GPRTemporary scratch(this); + writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR); + } + StorageOperand storage(this, node.child3()); GPRReg storageGPR = storage.gpr(); switch (node.arrayMode().type()) { - case Array::Int32: case Array::Contiguous: { - JSValueOperand value(this, node.child2()); - GPRReg valueGPR = value.gpr(); - - if (node.arrayMode().type() == Array::Int32 && !isInt32Speculation(m_state.forNode(node.child2()).m_type)) { - speculationCheck( - BadType, JSValueRegs(valueGPR), node.child2(), - m_jit.branch64(MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister)); - } - - if (node.arrayMode().type() != Array::Int32 && Heap::isWriteBarrierEnabled()) { - GPRTemporary scratch(this); - writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR); - } - m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); m_jit.store64(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight)); @@ -3193,43 +3114,7 @@ void SpeculativeJIT::compile(Node& node) break; } - case Array::Double: { - SpeculateDoubleOperand value(this, node.child2()); - FPRReg valueFPR = value.fpr(); - - if (!isRealNumberSpeculation(m_state.forNode(node.child2()).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR)); - } - - m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); - MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); - m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight)); - m_jit.add32(TrustedImm32(1), storageLengthGPR); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); - m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR); - - addSlowPathGenerator( - slowPathCall( - slowPath, this, operationArrayPushDouble, NoResult, storageLengthGPR, - valueFPR, baseGPR)); - - jsValueResult(storageLengthGPR, m_compileIndex); - break; - } - case Array::ArrayStorage: { - JSValueOperand value(this, node.child2()); - GPRReg valueGPR = value.gpr(); - - if (Heap::isWriteBarrierEnabled()) { - GPRTemporary scratch(this); - writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR); - } - m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); // Refuse to handle bizarre lengths. @@ -3267,17 +3152,13 @@ void SpeculativeJIT::compile(Node& node) StorageOperand storage(this, node.child2()); GPRTemporary value(this); GPRTemporary storageLength(this); - FPRTemporary temp(this); // This is kind of lame, since we don't always need it. I'm relying on the fact that we don't have FPR pressure, especially in code that uses pop(). GPRReg baseGPR = base.gpr(); GPRReg storageGPR = storage.gpr(); GPRReg valueGPR = value.gpr(); GPRReg storageLengthGPR = storageLength.gpr(); - FPRReg tempFPR = temp.fpr(); switch (node.arrayMode().type()) { - case Array::Int32: - case Array::Double: case Array::Contiguous: { m_jit.load32( MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); @@ -3286,27 +3167,14 @@ void SpeculativeJIT::compile(Node& node) m_jit.sub32(TrustedImm32(1), storageLengthGPR); m_jit.store32( storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); - MacroAssembler::Jump slowCase; - if (node.arrayMode().type() == Array::Double) { - m_jit.loadDouble( - MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight), - tempFPR); - // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old - // length and the new length. - m_jit.store64( - MacroAssembler::TrustedImm64((int64_t)0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight)); - slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR); - boxDouble(tempFPR, valueGPR); - } else { - m_jit.load64( - MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight), - valueGPR); - // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old - // length and the new length. - m_jit.store64( + m_jit.load64( + MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight), + valueGPR); + // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old + // length and the new length. + m_jit.store64( MacroAssembler::TrustedImm64((int64_t)0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight)); - slowCase = m_jit.branchTest64(MacroAssembler::Zero, valueGPR); - } + MacroAssembler::Jump slowCase = m_jit.branchTest64(MacroAssembler::Zero, valueGPR); addSlowPathGenerator( slowPathMove( @@ -3316,7 +3184,6 @@ void SpeculativeJIT::compile(Node& node) slowPathCall( slowCase, this, operationArrayPopAndRecoverLength, valueGPR, baseGPR)); - // We can't know for sure that the result is an int because of the slow paths. :-/ jsValueResult(valueGPR, m_compileIndex); break; } @@ -3471,16 +3338,10 @@ void SpeculativeJIT::compile(Node& node) case NewArray: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) { + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); - Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()); - ASSERT(structure->indexingType() == node.indexingType()); - ASSERT( - hasUndecided(structure->indexingType()) - || hasInt32(structure->indexingType()) - || hasDouble(structure->indexingType()) - || hasContiguous(structure->indexingType())); + ASSERT(hasContiguous(globalObject->arrayStructure()->indexingType())); unsigned numElements = node.numChildren(); @@ -3490,50 +3351,15 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); GPRReg storageGPR = storage.gpr(); - emitAllocateJSArray(structure, resultGPR, storageGPR, numElements); + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); // At this point, one way or another, resultGPR and storageGPR have pointers to // the JSArray and the Butterfly, respectively. - ASSERT(!hasUndecided(structure->indexingType()) || !node.numChildren()); - for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { - Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]; - switch (node.indexingType()) { - case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - CRASH(); - break; - case ALL_DOUBLE_INDEXING_TYPES: { - SpeculateDoubleOperand operand(this, use); - FPRReg opFPR = operand.fpr(); - if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); - } - - m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx)); - break; - } - case ALL_INT32_INDEXING_TYPES: - case ALL_CONTIGUOUS_INDEXING_TYPES: { - JSValueOperand operand(this, use); - GPRReg opGPR = operand.gpr(); - if (hasInt32(node.indexingType()) && !isInt32Speculation(m_state.forNode(use).m_type)) { - speculationCheck( - BadType, JSValueRegs(opGPR), use.index(), - m_jit.branch64(MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister)); - } - m_jit.store64(opGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx)); - break; - } - default: - CRASH(); - break; - } + JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); + GPRReg opGPR = operand.gpr(); + m_jit.store64(opGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx)); } // Yuck, we should *really* have a way of also returning the storageGPR. But @@ -3550,7 +3376,7 @@ void SpeculativeJIT::compile(Node& node) if (!node.numChildren()) { flushRegisters(); GPRResult result(this); - callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())); + callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructure()); cellResult(result.gpr(), m_compileIndex); break; } @@ -3560,65 +3386,11 @@ void SpeculativeJIT::compile(Node& node) EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0; for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { - // Need to perform the speculations that this node promises to perform. If we're - // emitting code here and the indexing type is not array storage then there is - // probably something hilarious going on and we're already failing at all the - // things, but at least we're going to be sound. - Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]; - switch (node.indexingType()) { - case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - CRASH(); - break; - case ALL_DOUBLE_INDEXING_TYPES: { - SpeculateDoubleOperand operand(this, use); - GPRTemporary scratch(this); - FPRReg opFPR = operand.fpr(); - GPRReg scratchGPR = scratch.gpr(); - if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) { - // FIXME: We need a way of profiling these, and we need to hoist them into - // SpeculateDoubleOperand. - speculationCheck( - BadType, JSValueRegs(), NoNode, - m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR)); - } - - m_jit.boxDouble(opFPR, scratchGPR); - m_jit.store64(scratchGPR, buffer + operandIdx); - break; - } - case ALL_INT32_INDEXING_TYPES: { - JSValueOperand operand(this, use); - GPRReg opGPR = operand.gpr(); - if (hasInt32(node.indexingType()) && !isInt32Speculation(m_state.forNode(use).m_type)) { - speculationCheck( - BadType, JSValueRegs(opGPR), use.index(), - m_jit.branch64(MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister)); - } - m_jit.store64(opGPR, buffer + operandIdx); - break; - } - case ALL_CONTIGUOUS_INDEXING_TYPES: - case ALL_ARRAY_STORAGE_INDEXING_TYPES: { - JSValueOperand operand(this, use); - GPRReg opGPR = operand.gpr(); - m_jit.store64(opGPR, buffer + operandIdx); - operand.use(); - break; - } - default: - CRASH(); - break; - } - } - - switch (node.indexingType()) { - case ALL_DOUBLE_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - useChildren(node); - break; - default: - break; + JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); + GPRReg opGPR = operand.gpr(); + operand.use(); + + m_jit.store64(opGPR, buffer + operandIdx); } flushRegisters(); @@ -3634,7 +3406,7 @@ void SpeculativeJIT::compile(Node& node) GPRResult result(this); callOperation( - operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), + operationNewArray, result.gpr(), globalObject->arrayStructure(), static_cast<void*>(buffer), node.numChildren()); if (scratchSize) { @@ -3650,26 +3422,18 @@ void SpeculativeJIT::compile(Node& node) case NewArrayWithSize: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) { + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); SpeculateStrictInt32Operand size(this, node.child1()); GPRTemporary result(this); GPRTemporary storage(this); GPRTemporary scratch(this); - GPRTemporary scratch2; GPRReg sizeGPR = size.gpr(); GPRReg resultGPR = result.gpr(); GPRReg storageGPR = storage.gpr(); GPRReg scratchGPR = scratch.gpr(); - GPRReg scratch2GPR = InvalidGPRReg; - - if (hasDouble(node.indexingType())) { - GPRTemporary realScratch2(this, size); - scratch2.adopt(realScratch2); - scratch2GPR = scratch2.gpr(); - } MacroAssembler::JumpList slowCases; slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX))); @@ -3682,28 +3446,17 @@ void SpeculativeJIT::compile(Node& node) emitAllocateBasicStorage(resultGPR, storageGPR)); m_jit.subPtr(scratchGPR, storageGPR); emitAllocateBasicJSObject<JSArray, MarkedBlock::None>( - TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), resultGPR, scratchGPR, + TrustedImmPtr(globalObject->arrayStructure()), resultGPR, scratchGPR, storageGPR, sizeof(JSArray), slowCases); m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); - if (hasDouble(node.indexingType())) { - m_jit.move(TrustedImm64(bitwise_cast<int64_t>(QNaN)), scratchGPR); - m_jit.move(sizeGPR, scratch2GPR); - MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratch2GPR); - MacroAssembler::Label loop = m_jit.label(); - m_jit.sub32(TrustedImm32(1), scratch2GPR); - m_jit.store64(scratchGPR, MacroAssembler::BaseIndex(storageGPR, scratch2GPR, MacroAssembler::TimesEight)); - m_jit.branchTest32(MacroAssembler::NonZero, scratch2GPR).linkTo(loop, &m_jit); - done.link(&m_jit); - } - addSlowPathGenerator(adoptPtr( new CallArrayAllocatorWithVariableSizeSlowPathGenerator( slowCases, this, operationNewArrayWithSize, resultGPR, - globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), - globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage), + globalObject->arrayStructure(), + globalObject->arrayStructureWithArrayStorage(), sizeGPR))); cellResult(resultGPR, m_compileIndex); @@ -3717,10 +3470,10 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); GPRReg structureGPR = selectScratchGPR(sizeGPR); MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)); - m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), structureGPR); + m_jit.move(TrustedImmPtr(globalObject->arrayStructure()), structureGPR); MacroAssembler::Jump done = m_jit.jump(); bigLength.link(&m_jit); - m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR); + m_jit.move(TrustedImmPtr(globalObject->arrayStructureWithArrayStorage()), structureGPR); done.link(&m_jit); callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR); cellResult(resultGPR, m_compileIndex); @@ -3767,8 +3520,7 @@ void SpeculativeJIT::compile(Node& node) case NewArrayBuffer: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - IndexingType indexingType = node.indexingType(); - if (!globalObject->isHavingABadTime() && !hasArrayStorage(indexingType)) { + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); unsigned numElements = node.numConstants(); @@ -3779,23 +3531,13 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); GPRReg storageGPR = storage.gpr(); - emitAllocateJSArray(globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), resultGPR, storageGPR, numElements); + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); - ASSERT(indexingType & IsArray); JSValue* data = m_jit.codeBlock()->constantBuffer(node.startConstant()); - if (indexingType == ArrayWithDouble) { - for (unsigned index = 0; index < node.numConstants(); ++index) { - double value = data[index].asNumber(); - m_jit.store64( - Imm64(bitwise_cast<int64_t>(value)), - MacroAssembler::Address(storageGPR, sizeof(double) * index)); - } - } else { - for (unsigned index = 0; index < node.numConstants(); ++index) { - m_jit.store64( - Imm64(JSValue::encode(data[index])), - MacroAssembler::Address(storageGPR, sizeof(JSValue) * index)); - } + for (unsigned index = 0; index < node.numConstants(); ++index) { + m_jit.store64( + Imm64(JSValue::encode(data[index])), + MacroAssembler::Address(storageGPR, sizeof(JSValue) * index)); } cellResult(resultGPR, m_compileIndex); @@ -3805,7 +3547,7 @@ void SpeculativeJIT::compile(Node& node) flushRegisters(); GPRResult result(this); - callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), node.startConstant(), node.numConstants()); + callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructure(), node.startConstant(), node.numConstants()); cellResult(result.gpr(), m_compileIndex); break; diff --git a/Source/JavaScriptCore/heap/ConservativeRoots.cpp b/Source/JavaScriptCore/heap/ConservativeRoots.cpp index 752ce2775..7fe22dfff 100644 --- a/Source/JavaScriptCore/heap/ConservativeRoots.cpp +++ b/Source/JavaScriptCore/heap/ConservativeRoots.cpp @@ -26,9 +26,9 @@ #include "config.h" #include "ConservativeRoots.h" -#include "CodeBlock.h" #include "CopiedSpace.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" +#include "CodeBlock.h" #include "DFGCodeBlocks.h" #include "JSCell.h" #include "JSObject.h" diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h index 83fdb08da..af36f55df 100644 --- a/Source/JavaScriptCore/heap/CopiedBlock.h +++ b/Source/JavaScriptCore/heap/CopiedBlock.h @@ -29,7 +29,7 @@ #include "BlockAllocator.h" #include "HeapBlock.h" #include "JSValue.h" -#include "JSValueInlines.h" +#include "JSValueInlineMethods.h" #include "Options.h" #include <wtf/Atomics.h> diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index e4141c1d7..c228f9460 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -26,7 +26,7 @@ #include "config.h" #include "CopiedSpace.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "GCActivityCallback.h" #include "Options.h" diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlines.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h index 9d222f549..c244015e7 100644 --- a/Source/JavaScriptCore/heap/CopiedSpaceInlines.h +++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CopiedSpaceInlines_h -#define CopiedSpaceInlines_h +#ifndef CopiedSpaceInlineMethods_h +#define CopiedSpaceInlineMethods_h #include "CopiedBlock.h" #include "CopiedSpace.h" @@ -182,5 +182,4 @@ inline CopiedBlock* CopiedSpace::blockFor(void* ptr) } // namespace JSC -#endif // CopiedSpaceInlines_h - +#endif diff --git a/Source/JavaScriptCore/heap/CopyVisitor.cpp b/Source/JavaScriptCore/heap/CopyVisitor.cpp index 22ab57882..ae826f0d2 100644 --- a/Source/JavaScriptCore/heap/CopyVisitor.cpp +++ b/Source/JavaScriptCore/heap/CopyVisitor.cpp @@ -26,7 +26,7 @@ #include "config.h" #include "CopyVisitor.h" -#include "CopyVisitorInlines.h" +#include "CopyVisitorInlineMethods.h" #include "GCThreadSharedData.h" #include "JSCell.h" #include "JSObject.h" diff --git a/Source/JavaScriptCore/heap/CopyVisitorInlines.h b/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h index bd7879429..eb7bd2e82 100644 --- a/Source/JavaScriptCore/heap/CopyVisitorInlines.h +++ b/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h @@ -23,8 +23,8 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CopyVisitorInlines_h -#define CopyVisitorInlines_h +#ifndef CopyVisitorInlineMethods_h +#define CopyVisitorInlineMethods_h #include "ClassInfo.h" #include "CopyVisitor.h" @@ -116,5 +116,4 @@ inline void CopyVisitor::didCopy(void* ptr, size_t bytes) } // namespace JSC -#endif // CopyVisitorInlines_h - +#endif diff --git a/Source/JavaScriptCore/heap/GCThread.cpp b/Source/JavaScriptCore/heap/GCThread.cpp index 7caa7d588..ce3bbedc9 100644 --- a/Source/JavaScriptCore/heap/GCThread.cpp +++ b/Source/JavaScriptCore/heap/GCThread.cpp @@ -27,7 +27,7 @@ #include "GCThread.h" #include "CopyVisitor.h" -#include "CopyVisitorInlines.h" +#include "CopyVisitorInlineMethods.h" #include "GCThreadSharedData.h" #include "SlotVisitor.h" #include <wtf/MainThread.h> diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp index cf12d4bcd..446b41c2f 100644 --- a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp +++ b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp @@ -27,12 +27,12 @@ #include "GCThreadSharedData.h" #include "CopyVisitor.h" -#include "CopyVisitorInlines.h" +#include "CopyVisitorInlineMethods.h" #include "GCThread.h" #include "JSGlobalData.h" #include "MarkStack.h" #include "SlotVisitor.h" -#include "SlotVisitorInlines.h" +#include "SlotVisitorInlineMethods.h" namespace JSC { diff --git a/Source/JavaScriptCore/heap/HandleStack.cpp b/Source/JavaScriptCore/heap/HandleStack.cpp index a5653c748..42eb326a5 100644 --- a/Source/JavaScriptCore/heap/HandleStack.cpp +++ b/Source/JavaScriptCore/heap/HandleStack.cpp @@ -27,8 +27,8 @@ #include "HandleStack.h" #include "HeapRootVisitor.h" +#include "JSValueInlineMethods.h" #include "JSObject.h" -#include "JSValueInlines.h" namespace JSC { diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index 0fb65e205..c455fc2b1 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -24,8 +24,8 @@ #include "CodeBlock.h" #include "ConservativeRoots.h" #include "CopiedSpace.h" -#include "CopiedSpaceInlines.h" -#include "CopyVisitorInlines.h" +#include "CopiedSpaceInlineMethods.h" +#include "CopyVisitorInlineMethods.h" #include "GCActivityCallback.h" #include "HeapRootVisitor.h" #include "HeapStatistics.h" diff --git a/Source/JavaScriptCore/heap/HeapRootVisitor.h b/Source/JavaScriptCore/heap/HeapRootVisitor.h index 5b11a5ead..9849d7c39 100644 --- a/Source/JavaScriptCore/heap/HeapRootVisitor.h +++ b/Source/JavaScriptCore/heap/HeapRootVisitor.h @@ -27,7 +27,7 @@ #define HeapRootVisitor_h #include "SlotVisitor.h" -#include "SlotVisitorInlines.h" +#include "SlotVisitorInlineMethods.h" namespace JSC { diff --git a/Source/JavaScriptCore/heap/HeapStatistics.cpp b/Source/JavaScriptCore/heap/HeapStatistics.cpp index 387621558..8340bfa37 100644 --- a/Source/JavaScriptCore/heap/HeapStatistics.cpp +++ b/Source/JavaScriptCore/heap/HeapStatistics.cpp @@ -41,8 +41,8 @@ namespace JSC { double HeapStatistics::s_startTime = 0.0; double HeapStatistics::s_endTime = 0.0; -Vector<double>* HeapStatistics::s_pauseTimeStarts = 0; -Vector<double>* HeapStatistics::s_pauseTimeEnds = 0; +Deque<double>* HeapStatistics::s_pauseTimeStarts = 0; +Deque<double>* HeapStatistics::s_pauseTimeEnds = 0; #if OS(UNIX) @@ -50,8 +50,8 @@ void HeapStatistics::initialize() { ASSERT(Options::recordGCPauseTimes()); s_startTime = WTF::monotonicallyIncreasingTime(); - s_pauseTimeStarts = new Vector<double>(); - s_pauseTimeEnds = new Vector<double>(); + s_pauseTimeStarts = new Deque<double>(); + s_pauseTimeEnds = new Deque<double>(); } void HeapStatistics::recordGCPauseTime(double start, double end) @@ -82,8 +82,8 @@ void HeapStatistics::logStatistics() if (Options::recordGCPauseTimes()) { dataLog(", \"pause_times\": ["); - Vector<double>::iterator startIt = s_pauseTimeStarts->begin(); - Vector<double>::iterator endIt = s_pauseTimeEnds->begin(); + Deque<double>::iterator startIt = s_pauseTimeStarts->begin(); + Deque<double>::iterator endIt = s_pauseTimeEnds->begin(); if (startIt != s_pauseTimeStarts->end() && endIt != s_pauseTimeEnds->end()) { dataLog("[%f, %f]", *startIt, *endIt); ++startIt; diff --git a/Source/JavaScriptCore/heap/HeapStatistics.h b/Source/JavaScriptCore/heap/HeapStatistics.h index ce7a40a79..0800f0c16 100644 --- a/Source/JavaScriptCore/heap/HeapStatistics.h +++ b/Source/JavaScriptCore/heap/HeapStatistics.h @@ -49,8 +49,8 @@ public: private: static void logStatistics(); - static Vector<double>* s_pauseTimeStarts; - static Vector<double>* s_pauseTimeEnds; + static Deque<double>* s_pauseTimeStarts; + static Deque<double>* s_pauseTimeEnds; static double s_startTime; static double s_endTime; }; diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index aa8785e9c..582439fd2 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -25,18 +25,18 @@ #include "config.h" #include "MarkStack.h" -#include "MarkStackInlines.h" +#include "MarkStackInlineMethods.h" -#include "ConservativeRoots.h" #include "CopiedSpace.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" +#include "ConservativeRoots.h" #include "Heap.h" #include "Options.h" #include "JSArray.h" #include "JSCell.h" #include "JSObject.h" -#include "SlotVisitorInlines.h" +#include "SlotVisitorInlineMethods.h" #include "Structure.h" #include "WriteBarrier.h" #include <wtf/Atomics.h> diff --git a/Source/JavaScriptCore/heap/MarkStackInlines.h b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h index 841ac06b8..d3276d7fa 100644 --- a/Source/JavaScriptCore/heap/MarkStackInlines.h +++ b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MarkStackInlines_h -#define MarkStackInlines_h +#ifndef MarkStackInlineMethods_h +#define MarkStackInlineMethods_h #include "GCThreadSharedData.h" #include "MarkStack.h" @@ -37,14 +37,14 @@ inline size_t MarkStackArray::postIncTop() ASSERT(result == m_topSegment->m_top++); return result; } - + inline size_t MarkStackArray::preDecTop() { size_t result = --m_top; ASSERT(result == --m_topSegment->m_top); return result; } - + inline void MarkStackArray::setTopForFullSegment() { ASSERT(m_topSegment->m_top == m_segmentCapacity); @@ -110,5 +110,4 @@ inline size_t MarkStackArray::size() } // namespace JSC -#endif // MarkStackInlines_h - +#endif diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp index 8b4d7397e..3919705d0 100644 --- a/Source/JavaScriptCore/heap/SlotVisitor.cpp +++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp @@ -3,7 +3,7 @@ #include "ConservativeRoots.h" #include "CopiedSpace.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "GCThread.h" #include "JSArray.h" #include "JSDestructibleObject.h" diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h index 34b1bc80b..dcd4b75ef 100644 --- a/Source/JavaScriptCore/heap/SlotVisitor.h +++ b/Source/JavaScriptCore/heap/SlotVisitor.h @@ -27,7 +27,7 @@ #define SlotVisitor_h #include "HandleTypes.h" -#include "MarkStackInlines.h" +#include "MarkStackInlineMethods.h" #include <wtf/text/StringHash.h> diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlines.h b/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h index b0f30b6ca..e5908bf36 100644 --- a/Source/JavaScriptCore/heap/SlotVisitorInlines.h +++ b/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h @@ -23,10 +23,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SlotVisitorInlines_h -#define SlotVisitorInlines_h +#ifndef SlotVisitorInlineMethods_h +#define SlotVisitorInlineMethods_h -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "Options.h" #include "SlotVisitor.h" @@ -170,5 +170,5 @@ inline void SlotVisitor::copyLater(void* ptr, size_t bytes) } // namespace JSC -#endif // SlotVisitorInlines_h +#endif // SlotVisitorInlineMethods_h diff --git a/Source/JavaScriptCore/jit/HostCallReturnValue.cpp b/Source/JavaScriptCore/jit/HostCallReturnValue.cpp index 967c499b9..c4d2e6ad9 100644 --- a/Source/JavaScriptCore/jit/HostCallReturnValue.cpp +++ b/Source/JavaScriptCore/jit/HostCallReturnValue.cpp @@ -29,7 +29,7 @@ #include "CallFrame.h" #include <wtf/InlineASM.h> #include "JSObject.h" -#include "JSValueInlines.h" +#include "JSValueInlineMethods.h" namespace JSC { diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp index ffd18b571..3102c7693 100644 --- a/Source/JavaScriptCore/jit/JIT.cpp +++ b/Source/JavaScriptCore/jit/JIT.cpp @@ -38,7 +38,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse #include <wtf/CryptographicallyRandomNumber.h> #include "DFGNode.h" // for DFG_SUCCESS_STATS #include "Interpreter.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index 9b0879fe2..dcf87d352 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -474,9 +474,7 @@ namespace JSC { // Property is int-checked and zero extended. Base is cell checked. // Structure is already profiled. Returns the slow cases. Fall-through // case contains result in regT0, and it is not yet profiled. - JumpList emitInt32GetByVal(Instruction* instruction, PatchableJump& badType) { return emitContiguousGetByVal(instruction, badType, Int32Shape); } - JumpList emitDoubleGetByVal(Instruction*, PatchableJump& badType); - JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape); + JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType); JumpList emitArrayStorageGetByVal(Instruction*, PatchableJump& badType); JumpList emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize, TypedArraySignedness); JumpList emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize); @@ -485,20 +483,7 @@ namespace JSC { // The value to store is not yet loaded. Property is int-checked and // zero-extended. Base is cell checked. Structure is already profiled. // returns the slow cases. - JumpList emitInt32PutByVal(Instruction* currentInstruction, PatchableJump& badType) - { - return emitGenericContiguousPutByVal<Int32Shape>(currentInstruction, badType); - } - JumpList emitDoublePutByVal(Instruction* currentInstruction, PatchableJump& badType) - { - return emitGenericContiguousPutByVal<DoubleShape>(currentInstruction, badType); - } - JumpList emitContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) - { - return emitGenericContiguousPutByVal<ContiguousShape>(currentInstruction, badType); - } - template<IndexingType indexingShape> - JumpList emitGenericContiguousPutByVal(Instruction*, PatchableJump& badType); + JumpList emitContiguousPutByVal(Instruction*, PatchableJump& badType); JumpList emitArrayStoragePutByVal(Instruction*, PatchableJump& badType); JumpList emitIntTypedArrayPutByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize, TypedArraySignedness, TypedArrayRounding); JumpList emitFloatTypedArrayPutByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize); diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp index bcb3dd74a..21d59bc33 100644 --- a/Source/JavaScriptCore/jit/JITArithmetic.cpp +++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp @@ -29,7 +29,7 @@ #include "JIT.h" #include "CodeBlock.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JITStubs.h" #include "JSArray.h" @@ -1090,20 +1090,18 @@ void JIT::emit_op_div(Instruction* currentInstruction) // access). So if we are DFG compiling anything in the program, we want this code to // ensure that it produces integers whenever possible. + // FIXME: This will fail to convert to integer if the result is zero. We should + // distinguish between positive zero and negative zero here. + JumpList notInteger; branchConvertDoubleToInt32(fpRegT0, regT0, notInteger, fpRegT1); // If we've got an integer, we might as well make that the result of the division. emitFastArithReTagImmediate(regT0, regT0); Jump isInteger = jump(); notInteger.link(this); - moveDoubleTo64(fpRegT0, regT0); - Jump doubleZero = branchTest64(Zero, regT0); add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter)); + moveDoubleTo64(fpRegT0, regT0); sub64(tagTypeNumberRegister, regT0); - Jump trueDouble = jump(); - doubleZero.link(this); - move(tagTypeNumberRegister, regT0); - trueDouble.link(this); isInteger.link(this); #else // Double result. diff --git a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp index 960d06091..62a359eeb 100644 --- a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp +++ b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp @@ -30,7 +30,7 @@ #include "JIT.h" #include "CodeBlock.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JITStubs.h" #include "JSArray.h" diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp index 006c5b741..074bf7f97 100644 --- a/Source/JavaScriptCore/jit/JITCall.cpp +++ b/Source/JavaScriptCore/jit/JITCall.cpp @@ -31,7 +31,7 @@ #include "Arguments.h" #include "CodeBlock.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp index ecd5cf126..ad827cdf9 100644 --- a/Source/JavaScriptCore/jit/JITCall32_64.cpp +++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp @@ -32,7 +32,7 @@ #include "Arguments.h" #include "CodeBlock.h" #include "Interpreter.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" diff --git a/Source/JavaScriptCore/jit/JITExceptions.cpp b/Source/JavaScriptCore/jit/JITExceptions.cpp index aeb869474..f6cec24bd 100644 --- a/Source/JavaScriptCore/jit/JITExceptions.cpp +++ b/Source/JavaScriptCore/jit/JITExceptions.cpp @@ -39,7 +39,7 @@ namespace JSC { ExceptionHandler genericThrow(JSGlobalData* globalData, ExecState* callFrame, JSValue exceptionValue, unsigned vPCIndex) { ASSERT(exceptionValue); - + globalData->exception = JSValue(); HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex); // This may update callFrame & exceptionValue! globalData->exception = exceptionValue; diff --git a/Source/JavaScriptCore/jit/JITInlines.h b/Source/JavaScriptCore/jit/JITInlineMethods.h index e6f95b94c..410bdf710 100644 --- a/Source/JavaScriptCore/jit/JITInlines.h +++ b/Source/JavaScriptCore/jit/JITInlineMethods.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JITInlines_h -#define JITInlines_h +#ifndef JITInlineMethods_h +#define JITInlineMethods_h #if ENABLE(JIT) @@ -528,12 +528,12 @@ inline void JIT::emitArrayProfileStoreToHoleSpecialCase(ArrayProfile* arrayProfi #endif } -static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capability) +static inline bool arrayProfileSaw(ArrayProfile* profile, IndexingType capability) { #if ENABLE(VALUE_PROFILER) - return arrayModesInclude(arrayModes, capability); + return !!(profile->observedArrayModes() & (asArrayModes(NonArray | capability) | asArrayModes(ArrayClass | capability))); #else - UNUSED_PARAM(arrayModes); + UNUSED_PARAM(profile); UNUSED_PARAM(capability); return false; #endif @@ -541,20 +541,9 @@ static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capabilit inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile) { -#if ENABLE(VALUE_PROFILER) - profile->computeUpdatedPrediction(m_codeBlock); - ArrayModes arrayModes = profile->observedArrayModes(); - if (arrayProfileSaw(arrayModes, DoubleShape)) - return JITDouble; - if (arrayProfileSaw(arrayModes, Int32Shape)) - return JITInt32; - if (arrayProfileSaw(arrayModes, ArrayStorageShape)) + if (arrayProfileSaw(profile, ArrayStorageShape)) return JITArrayStorage; return JITContiguous; -#else - UNUSED_PARAM(profile); - return JITContiguous; -#endif } #if USE(JSVALUE32_64) @@ -1009,5 +998,4 @@ ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg) #endif // ENABLE(JIT) -#endif // JITInlines_h - +#endif diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp index 3053918b8..4fb9d8cd5 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp @@ -29,9 +29,9 @@ #include "JIT.h" #include "Arguments.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "Heap.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSCell.h" @@ -1952,7 +1952,6 @@ void JIT::emit_op_new_array(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_new_array); stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand)); stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); - stubCall.addArgument(TrustedImmPtr(currentInstruction[4].u.arrayAllocationProfile)); stubCall.call(currentInstruction[1].u.operand); } @@ -1964,7 +1963,6 @@ void JIT::emit_op_new_array_with_size(Instruction* currentInstruction) #else stubCall.addArgument(currentInstruction[2].u.operand); #endif - stubCall.addArgument(TrustedImmPtr(currentInstruction[3].u.arrayAllocationProfile)); stubCall.call(currentInstruction[1].u.operand); } @@ -1973,7 +1971,6 @@ void JIT::emit_op_new_array_buffer(Instruction* currentInstruction) JITStubCall stubCall(this, cti_op_new_array_buffer); stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand)); stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); - stubCall.addArgument(TrustedImmPtr(currentInstruction[4].u.arrayAllocationProfile)); stubCall.call(currentInstruction[1].u.operand); } diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp index 23361c099..9c5d260ab 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -30,7 +30,7 @@ #if USE(JSVALUE32_64) #include "JIT.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSCell.h" diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp index 3110be38c..6362598f4 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -32,7 +32,7 @@ #include "GCAwareJITStubRoutine.h" #include "GetterSetter.h" #include "Interpreter.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" @@ -98,7 +98,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) unsigned base = currentInstruction[2].u.operand; unsigned property = currentInstruction[3].u.operand; ArrayProfile* profile = currentInstruction[4].u.arrayProfile; - + emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -120,12 +120,6 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) JITArrayMode mode = chooseArrayMode(profile); switch (mode) { - case JITInt32: - slowCases = emitInt32GetByVal(currentInstruction, badType); - break; - case JITDouble: - slowCases = emitDoubleGetByVal(currentInstruction, badType); - break; case JITContiguous: slowCases = emitContiguousGetByVal(currentInstruction, badType); break; @@ -154,26 +148,11 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); } -JIT::JumpList JIT::emitDoubleGetByVal(Instruction*, PatchableJump& badType) +JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType) { JumpList slowCases; - badType = patchableBranch32(NotEqual, regT2, TrustedImm32(DoubleShape)); - loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); - slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfPublicLength()))); - loadDouble(BaseIndex(regT2, regT1, TimesEight), fpRegT0); - slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0)); - moveDoubleTo64(fpRegT0, regT0); - sub64(tagTypeNumberRegister, regT0); - - return slowCases; -} - -JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape) -{ - JumpList slowCases; - - badType = patchableBranch32(NotEqual, regT2, TrustedImm32(expectedShape)); + badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ContiguousShape)); loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfPublicLength()))); load64(BaseIndex(regT2, regT1, TimesEight), regT0); @@ -325,12 +304,6 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) JITArrayMode mode = chooseArrayMode(profile); switch (mode) { - case JITInt32: - slowCases = emitInt32PutByVal(currentInstruction, badType); - break; - case JITDouble: - slowCases = emitDoublePutByVal(currentInstruction, badType); - break; case JITContiguous: slowCases = emitContiguousPutByVal(currentInstruction, badType); break; @@ -352,49 +325,24 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) emitWriteBarrier(regT0, regT3, regT1, regT3, ShouldFilterImmediates, WriteBarrierForPropertyAccess); } -template<IndexingType indexingShape> -JIT::JumpList JIT::emitGenericContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) +JIT::JumpList JIT::emitContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) { unsigned value = currentInstruction[3].u.operand; ArrayProfile* profile = currentInstruction[4].u.arrayProfile; - JumpList slowCases; - - badType = patchableBranch32(NotEqual, regT2, TrustedImm32(indexingShape)); + badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ContiguousShape)); loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); Jump outOfBounds = branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfPublicLength())); Label storeResult = label(); emitGetVirtualRegister(value, regT3); - switch (indexingShape) { - case Int32Shape: - slowCases.append(emitJumpIfNotImmediateInteger(regT3)); - store64(regT3, BaseIndex(regT2, regT1, TimesEight)); - break; - case DoubleShape: { - Jump notInt = emitJumpIfNotImmediateInteger(regT3); - convertInt32ToDouble(regT3, fpRegT0); - Jump ready = jump(); - notInt.link(this); - add64(tagTypeNumberRegister, regT3); - move64ToDouble(regT3, fpRegT0); - slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0)); - ready.link(this); - storeDouble(fpRegT0, BaseIndex(regT2, regT1, TimesEight)); - break; - } - case ContiguousShape: - store64(regT3, BaseIndex(regT2, regT1, TimesEight)); - break; - default: - CRASH(); - break; - } + store64(regT3, BaseIndex(regT2, regT1, TimesEight)); Jump done = jump(); outOfBounds.link(this); + JumpList slowCases; slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfVectorLength()))); emitArrayProfileStoreToHoleSpecialCase(profile); @@ -446,23 +394,12 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas unsigned base = currentInstruction[1].u.operand; unsigned property = currentInstruction[2].u.operand; unsigned value = currentInstruction[3].u.operand; - ArrayProfile* profile = currentInstruction[4].u.arrayProfile; linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base not array check linkSlowCase(iter); // out of bounds - JITArrayMode mode = chooseArrayMode(profile); - switch (mode) { - case JITInt32: - case JITDouble: - linkSlowCase(iter); // value type check - break; - default: - break; - } - Label slowPath = label(); JITStubCall stubPutByValCall(this, cti_op_put_by_val); @@ -1375,12 +1312,6 @@ void JIT::privateCompileGetByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd JumpList slowCases; switch (arrayMode) { - case JITInt32: - slowCases = emitInt32GetByVal(currentInstruction, badType); - break; - case JITDouble: - slowCases = emitDoubleGetByVal(currentInstruction, badType); - break; case JITContiguous: slowCases = emitContiguousGetByVal(currentInstruction, badType); break; @@ -1444,12 +1375,6 @@ void JIT::privateCompilePutByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd JumpList slowCases; switch (arrayMode) { - case JITInt32: - slowCases = emitInt32PutByVal(currentInstruction, badType); - break; - case JITDouble: - slowCases = emitDoublePutByVal(currentInstruction, badType); - break; case JITContiguous: slowCases = emitContiguousPutByVal(currentInstruction, badType); break; diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index 414827420..939766f04 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -32,7 +32,7 @@ #include "CodeBlock.h" #include "GCAwareJITStubRoutine.h" #include "Interpreter.h" -#include "JITInlines.h" +#include "JITInlineMethods.h" #include "JITStubCall.h" #include "JSArray.h" #include "JSFunction.h" @@ -153,12 +153,6 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) JITArrayMode mode = chooseArrayMode(profile); switch (mode) { - case JITInt32: - slowCases = emitInt32GetByVal(currentInstruction, badType); - break; - case JITDouble: - slowCases = emitDoubleGetByVal(currentInstruction, badType); - break; case JITContiguous: slowCases = emitContiguousGetByVal(currentInstruction, badType); break; @@ -187,11 +181,11 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); } -JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape) +JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType) { JumpList slowCases; - badType = patchableBranch32(NotEqual, regT1, TrustedImm32(expectedShape)); + badType = patchableBranch32(NotEqual, regT1, TrustedImm32(ContiguousShape)); loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength()))); @@ -203,22 +197,6 @@ JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType, return slowCases; } -JIT::JumpList JIT::emitDoubleGetByVal(Instruction*, PatchableJump& badType) -{ - JumpList slowCases; - - badType = patchableBranch32(NotEqual, regT1, TrustedImm32(DoubleShape)); - - loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); - slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength()))); - - loadDouble(BaseIndex(regT3, regT2, TimesEight), fpRegT0); - slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0)); - moveDoubleToInts(fpRegT0, regT0, regT1); - - return slowCases; -} - JIT::JumpList JIT::emitArrayStorageGetByVal(Instruction*, PatchableJump& badType) { JumpList slowCases; @@ -292,12 +270,6 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) JITArrayMode mode = chooseArrayMode(profile); switch (mode) { - case JITInt32: - slowCases = emitInt32PutByVal(currentInstruction, badType); - break; - case JITDouble: - slowCases = emitDoublePutByVal(currentInstruction, badType); - break; case JITContiguous: slowCases = emitContiguousPutByVal(currentInstruction, badType); break; @@ -317,8 +289,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); } -template<IndexingType indexingShape> -JIT::JumpList JIT::emitGenericContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) +JIT::JumpList JIT::emitContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) { unsigned value = currentInstruction[3].u.operand; ArrayProfile* profile = currentInstruction[4].u.arrayProfile; @@ -332,30 +303,8 @@ JIT::JumpList JIT::emitGenericContiguousPutByVal(Instruction* currentInstruction Label storeResult = label(); emitLoad(value, regT1, regT0); - switch (indexingShape) { - case Int32Shape: - slowCases.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); - // Fall through. - case ContiguousShape: - store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - break; - case DoubleShape: { - Jump notInt = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)); - convertInt32ToDouble(regT0, fpRegT0); - Jump ready = jump(); - notInt.link(this); - moveIntsToDouble(regT0, regT1, fpRegT0, fpRegT1); - slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0)); - ready.link(this); - storeDouble(fpRegT0, BaseIndex(regT3, regT2, TimesEight)); - break; - } - default: - CRASH(); - break; - } - + store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); Jump done = jump(); outOfBounds.link(this); @@ -415,23 +364,12 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas unsigned base = currentInstruction[1].u.operand; unsigned property = currentInstruction[2].u.operand; unsigned value = currentInstruction[3].u.operand; - ArrayProfile* profile = currentInstruction[4].u.arrayProfile; linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base not array check linkSlowCase(iter); // out of bounds - JITArrayMode mode = chooseArrayMode(profile); - switch (mode) { - case JITInt32: - case JITDouble: - linkSlowCase(iter); // value type check - break; - default: - break; - } - Label slowPath = label(); JITStubCall stubPutByValCall(this, cti_op_put_by_val); diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index 521dfacfd..5ddb98dee 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -1877,11 +1877,6 @@ DEFINE_STUB_FUNCTION(void, optimize) ASSERT(optimizedCodeBlock->getJITType() == JITCode::DFGJIT); if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) { - if (Options::showDFGDisassembly()) { - dataLog( - "Performing OSR from code block %p to code block %p, address %p to %p.\n", - codeBlock, optimizedCodeBlock, (STUB_RETURN_ADDRESS).value(), address); - } #if ENABLE(JIT_VERBOSE_OSR) dataLog("Optimizing %p succeeded, performing OSR after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter()); #endif @@ -2233,21 +2228,21 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_array) { STUB_INIT_STACK_FRAME(stackFrame); - return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), reinterpret_cast<JSValue*>(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()]), stackFrame.args[1].int32()); + return constructArray(stackFrame.callFrame, reinterpret_cast<JSValue*>(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()]), stackFrame.args[1].int32()); } DEFINE_STUB_FUNCTION(JSObject*, op_new_array_with_size) { STUB_INIT_STACK_FRAME(stackFrame); - return constructArrayWithSizeQuirk(stackFrame.callFrame, stackFrame.args[1].arrayAllocationProfile(), stackFrame.callFrame->lexicalGlobalObject(), stackFrame.args[0].jsValue()); + return constructArrayWithSizeQuirk(stackFrame.callFrame, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.args[0].jsValue()); } DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer) { STUB_INIT_STACK_FRAME(stackFrame); - return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32()); + return constructArray(stackFrame.callFrame, stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32()); } DEFINE_STUB_FUNCTION(void, op_init_global_const_check) @@ -2475,7 +2470,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) JSValue baseValue = stackFrame.args[0].jsValue(); JSValue subscript = stackFrame.args[1].jsValue(); JSValue value = stackFrame.args[2].jsValue(); - + if (baseValue.isObject() && subscript.isInt32()) { // See if it's worth optimizing at all. JSObject* object = asObject(baseValue); diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h index 3bf13bbdf..5761236b1 100644 --- a/Source/JavaScriptCore/jit/JITStubs.h +++ b/Source/JavaScriptCore/jit/JITStubs.h @@ -45,7 +45,6 @@ namespace JSC { struct StructureStubInfo; - class ArrayAllocationProfile; class CodeBlock; class ExecutablePool; class FunctionExecutable; @@ -86,7 +85,6 @@ namespace JSC { ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); } ResolveOperations* resolveOperations() { return static_cast<ResolveOperations*>(asPointer); } PutToBaseOperation* putToBaseOperation() { return static_cast<PutToBaseOperation*>(asPointer); } - ArrayAllocationProfile* arrayAllocationProfile() { return static_cast<ArrayAllocationProfile*>(asPointer); } }; struct TrampolineStructure { diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp index 07a05b0c9..b8cf49da6 100644 --- a/Source/JavaScriptCore/jsc.cpp +++ b/Source/JavaScriptCore/jsc.cpp @@ -22,10 +22,10 @@ #include "config.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" #include "BytecodeGenerator.h" #include "Completion.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "ExceptionHelpers.h" #include "HeapStatistics.h" #include "InitializeThreading.h" @@ -231,7 +231,7 @@ protected: addConstructableFunction(globalData, "Float32Array", constructJSFloat32Array, 1); addConstructableFunction(globalData, "Float64Array", constructJSFloat64Array, 1); - JSArray* array = constructEmptyArray(globalExec(), 0); + JSArray* array = constructEmptyArray(globalExec()); for (size_t i = 0; i < arguments.size(); ++i) array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i])); putDirect(globalData, Identifier(globalExec(), "arguments"), array); diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index 8a578ffac..ba44bf404 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -275,7 +275,7 @@ inline bool shouldJIT(ExecState* exec) // Returns true if we should try to OSR. inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec) { - codeBlock->updateAllValueProfilePredictions(); + codeBlock->updateAllPredictions(); if (!codeBlock->checkIfJITThresholdReached()) { #if ENABLE(JIT_VERBOSE_OSR) @@ -510,19 +510,19 @@ LLINT_SLOW_PATH_DECL(slow_path_new_object) LLINT_SLOW_PATH_DECL(slow_path_new_array) { LLINT_BEGIN(); - LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand)); + LLINT_RETURN(constructArray(exec, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand)); } LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size) { LLINT_BEGIN(); - LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue())); + LLINT_RETURN(constructArrayWithSizeQuirk(exec, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue())); } LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer) { LLINT_BEGIN(); - LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand)); + LLINT_RETURN(constructArray(exec, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand)); } LLINT_SLOW_PATH_DECL(slow_path_new_regexp) diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm index 00d5c4f6f..ba5b67df4 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm @@ -88,13 +88,10 @@ else end # Constant for reasoning about butterflies. -const IsArray = 1 -const IndexingShapeMask = 30 -const NoIndexingShape = 0 -const Int32Shape = 20 -const DoubleShape = 22 -const ContiguousShape = 26 -const ArrayStorageShape = 28 +const IsArray = 1 +const IndexingShapeMask = 30 +const ContiguousShape = 26 +const ArrayStorageShape = 28 const SlowPutArrayStorageShape = 30 # Type constants. @@ -465,19 +462,19 @@ end _llint_op_new_array: traceExecution() callSlowPath(_llint_slow_path_new_array) - dispatch(5) + dispatch(4) _llint_op_new_array_with_size: traceExecution() callSlowPath(_llint_slow_path_new_array_with_size) - dispatch(4) + dispatch(3) _llint_op_new_array_buffer: traceExecution() callSlowPath(_llint_slow_path_new_array_buffer) - dispatch(5) + dispatch(4) _llint_op_new_regexp: diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm index e3ef909f5..ffb146247 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm @@ -1185,9 +1185,7 @@ _llint_op_get_by_val: loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow) loadp JSObject::m_butterfly[t0], t3 andi IndexingShapeMask, t2 - bieq t2, Int32Shape, .opGetByValIsContiguous bineq t2, ContiguousShape, .opGetByValNotContiguous -.opGetByValIsContiguous: biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow loadi TagOffset[t3, t1, 8], t2 @@ -1195,16 +1193,6 @@ _llint_op_get_by_val: jmp .opGetByValDone .opGetByValNotContiguous: - bineq t2, DoubleShape, .opGetByValNotDouble - biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow - loadd [t3, t1, 8], ft0 - bdnequn ft0, ft0, .opGetByValSlow - # FIXME: This could be massively optimized. - fd2ii ft0, t1, t2 - loadi 4[PC], t0 - jmp .opGetByValNotEmpty - -.opGetByValNotDouble: subi ArrayStorageShape, t2 bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow @@ -1214,7 +1202,6 @@ _llint_op_get_by_val: .opGetByValDone: loadi 4[PC], t0 bieq t2, EmptyValueTag, .opGetByValSlow -.opGetByValNotEmpty: storei t2, TagOffset[cfr, t0, 8] storei t1, PayloadOffset[cfr, t0, 8] loadi 20[PC], t0 @@ -1283,24 +1270,6 @@ _llint_op_get_by_pname: dispatch(7) -macro contiguousPutByVal(storeCallback) - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds -.storeResult: - loadi 12[PC], t2 - storeCallback(t2, t1, t0, t3) - dispatch(5) - -.outOfBounds: - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow - if VALUE_PROFILER - loadp 16[PC], t2 - storeb 1, ArrayProfile::m_mayStoreToHole[t2] - end - addi 1, t3, t2 - storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .storeResult -end - _llint_op_put_by_val: traceExecution() loadi 4[PC], t0 @@ -1312,42 +1281,26 @@ _llint_op_put_by_val: loadConstantOrVariablePayload(t0, Int32Tag, t3, .opPutByValSlow) loadp JSObject::m_butterfly[t1], t0 andi IndexingShapeMask, t2 - bineq t2, Int32Shape, .opPutByValNotInt32 - contiguousPutByVal( - macro (operand, scratch, base, index) - loadConstantOrVariablePayload(operand, Int32Tag, scratch, .opPutByValSlow) - storei Int32Tag, TagOffset[base, index, 8] - storei scratch, PayloadOffset[base, index, 8] - end) + bineq t2, ContiguousShape, .opPutByValNotContiguous -.opPutByValNotInt32: - bineq t2, DoubleShape, .opPutByValNotDouble - contiguousPutByVal( - macro (operand, scratch, base, index) - const tag = scratch - const payload = operand - loadConstantOrVariable2Reg(operand, tag, payload) - bineq tag, Int32Tag, .notInt - ci2d payload, ft0 - jmp .ready - .notInt: - fii2d payload, tag, ft0 - bdnequn ft0, ft0, .opPutByValSlow - .ready: - stored ft0, [base, index, 8] - end) + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds +.opPutByValContiguousStoreResult: + loadi 12[PC], t2 + loadConstantOrVariable2Reg(t2, t1, t2) + writeBarrier(t1, t2) + storei t1, TagOffset[t0, t3, 8] + storei t2, PayloadOffset[t0, t3, 8] + dispatch(5) -.opPutByValNotDouble: - bineq t2, ContiguousShape, .opPutByValNotContiguous - contiguousPutByVal( - macro (operand, scratch, base, index) - const tag = scratch - const payload = operand - loadConstantOrVariable2Reg(operand, tag, payload) - writeBarrier(tag, payload) - storei tag, TagOffset[base, index, 8] - storei payload, PayloadOffset[base, index, 8] - end) +.opPutByValContiguousOutOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + if VALUE_PROFILER + loadp 16[PC], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .opPutByValContiguousStoreResult .opPutByValNotContiguous: bineq t2, ArrayStorageShape, .opPutByValSlow diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm index d8a293337..c9900b343 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm @@ -1025,9 +1025,7 @@ _llint_op_get_by_val: sxi2q t1, t1 loadp JSObject::m_butterfly[t0], t3 andi IndexingShapeMask, t2 - bieq t2, Int32Shape, .opGetByValIsContiguous bineq t2, ContiguousShape, .opGetByValNotContiguous -.opGetByValIsContiguous: biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow loadisFromInstruction(1, t0) @@ -1036,16 +1034,6 @@ _llint_op_get_by_val: jmp .opGetByValDone .opGetByValNotContiguous: - bineq t2, DoubleShape, .opGetByValNotDouble - biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow - loadis 8[PB, PC, 8], t0 - loadd [t3, t1, 8], ft0 - bdnequn ft0, ft0, .opGetByValSlow - fd2q ft0, t2 - subq tagTypeNumber, t2 - jmp .opGetByValDone - -.opGetByValNotDouble: subi ArrayStorageShape, t2 bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow @@ -1121,24 +1109,6 @@ _llint_op_get_by_pname: dispatch(7) -macro contiguousPutByVal(storeCallback) - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds -.storeResult: - loadisFromInstruction(3, t2) - storeCallback(t2, t1, [t0, t3, 8]) - dispatch(5) - -.outOfBounds: - biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow - if VALUE_PROFILER - loadp 32[PB, PC, 8], t2 - storeb 1, ArrayProfile::m_mayStoreToHole[t2] - end - addi 1, t3, t2 - storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .storeResult -end - _llint_op_put_by_val: traceExecution() loadisFromInstruction(1, t0) @@ -1151,38 +1121,25 @@ _llint_op_put_by_val: sxi2q t3, t3 loadp JSObject::m_butterfly[t1], t0 andi IndexingShapeMask, t2 - bineq t2, Int32Shape, .opPutByValNotInt32 - contiguousPutByVal( - macro (operand, scratch, address) - loadConstantOrVariable(operand, scratch) - bpb scratch, tagTypeNumber, .opPutByValSlow - storep scratch, address - end) - -.opPutByValNotInt32: - bineq t2, DoubleShape, .opPutByValNotDouble - contiguousPutByVal( - macro (operand, scratch, address) - loadConstantOrVariable(operand, scratch) - bqb scratch, tagTypeNumber, .notInt - ci2d scratch, ft0 - jmp .ready - .notInt: - addp tagTypeNumber, scratch - fq2d scratch, ft0 - bdnequn ft0, ft0, .opPutByValSlow - .ready: - stored ft0, address - end) - -.opPutByValNotDouble: bineq t2, ContiguousShape, .opPutByValNotContiguous - contiguousPutByVal( - macro (operand, scratch, address) - loadConstantOrVariable(operand, scratch) - writeBarrier(scratch) - storep scratch, address - end) + + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds +.opPutByValContiguousStoreResult: + loadisFromInstruction(3, t2) + loadConstantOrVariable(t2, t1) + writeBarrier(t1) + storeq t1, [t0, t3, 8] + dispatch(5) + +.opPutByValContiguousOutOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + if VALUE_PROFILER + loadpFromInstruction(4, t2) + storeb 1, ArrayProfile::m_mayStoreToHole[t2] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .opPutByValContiguousStoreResult .opPutByValNotContiguous: bineq t2, ArrayStorageShape, .opPutByValSlow diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb index f78b43912..67cbd14b0 100644 --- a/Source/JavaScriptCore/offlineasm/x86.rb +++ b/Source/JavaScriptCore/offlineasm/x86.rb @@ -764,16 +764,11 @@ class Instruction when "ci2d" $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}" when "bdeq" + isUnordered = LocalLabel.unique("bdeq") $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}" - if operands[0] == operands[1] - # This is just a jump ordered, which is a jnp. - $asm.puts "jnp #{operands[2].asmLabel}" - else - isUnordered = LocalLabel.unique("bdeq") - $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}" - $asm.puts "je #{LabelReference.new(codeOrigin, operands[2]).asmLabel}" - isUnordered.lower("X86") - end + $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}" + $asm.puts "je #{LabelReference.new(codeOrigin, operands[2]).asmLabel}" + isUnordered.lower("X86") when "bdneq" handleX86DoubleBranch("jne", :normal) when "bdgt" @@ -787,19 +782,14 @@ class Instruction when "bdequn" handleX86DoubleBranch("je", :normal) when "bdnequn" + isUnordered = LocalLabel.unique("bdnequn") + isEqual = LocalLabel.unique("bdnequn") $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}" - if operands[0] == operands[1] - # This is just a jump unordered, which is a jp. - $asm.puts "jp #{operands[2].asmLabel}" - else - isUnordered = LocalLabel.unique("bdnequn") - isEqual = LocalLabel.unique("bdnequn") - $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}" - $asm.puts "je #{LabelReference.new(codeOrigin, isEqual).asmLabel}" - isUnordered.lower("X86") - $asm.puts "jmp #{operands[2].asmLabel}" - isEqual.lower("X86") - end + $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}" + $asm.puts "je #{LabelReference.new(codeOrigin, isEqual).asmLabel}" + isUnordered.lower("X86") + $asm.puts "jmp #{operands[2].asmLabel}" + isEqual.lower("X86") when "bdgtun" handleX86DoubleBranch("jb", :reverse) when "bdgtequn" @@ -1125,7 +1115,7 @@ class Instruction $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}" $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7" $asm.puts "psrlq $32, %xmm7" - $asm.puts "movd %xmm7, #{operands[2].x86Operand(:int)}" + $asm.puts "movsd %xmm7, #{operands[2].x86Operand(:int)}" when "fq2d" $asm.puts "movd #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}" when "fd2q" diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h index 8ae991422..7961d4bc8 100644 --- a/Source/JavaScriptCore/runtime/Arguments.h +++ b/Source/JavaScriptCore/runtime/Arguments.h @@ -34,246 +34,246 @@ namespace JSC { -class Arguments : public JSDestructibleObject { - friend class JIT; - friend class DFG::SpeculativeJIT; -public: - typedef JSDestructibleObject Base; + class Arguments : public JSDestructibleObject { + friend class JIT; + friend class DFG::SpeculativeJIT; + public: + typedef JSDestructibleObject Base; + + static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame) + { + Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame); + arguments->finishCreation(callFrame); + return arguments; + } + + static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame, InlineCallFrame* inlineCallFrame) + { + Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame); + arguments->finishCreation(callFrame, inlineCallFrame); + return arguments; + } + + enum { MaxArguments = 0x10000 }; + + private: + enum NoParametersType { NoParameters }; + + Arguments(CallFrame*); + Arguments(CallFrame*, NoParametersType); + + void tearOffForInlineCallFrame(JSGlobalData& globalData, Register*, InlineCallFrame*); - static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame) + public: + static const ClassInfo s_info; + + static void visitChildren(JSCell*, SlotVisitor&); + + void fillArgList(ExecState*, MarkedArgumentBuffer&); + + uint32_t length(ExecState* exec) const + { + if (UNLIKELY(m_overrodeLength)) + return get(exec, exec->propertyNames().length).toUInt32(exec); + return m_numArguments; + } + + void copyToArguments(ExecState*, CallFrame*, uint32_t length); + void tearOff(CallFrame*); + void tearOff(CallFrame*, InlineCallFrame*); + bool isTornOff() const { return m_registerArray; } + void didTearOffActivation(ExecState*, JSActivation*); + + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); + } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + + void finishCreation(CallFrame*); + void finishCreation(CallFrame*, InlineCallFrame*); + + private: + static void destroy(JSCell*); + static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); + static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&); + static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); + static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); + static bool deleteProperty(JSCell*, ExecState*, PropertyName); + static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); + static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); + void createStrictModeCallerIfNecessary(ExecState*); + void createStrictModeCalleeIfNecessary(ExecState*); + + bool isArgument(size_t); + bool trySetArgument(JSGlobalData&, size_t argument, JSValue); + JSValue tryGetArgument(size_t argument); + bool isDeletedArgument(size_t); + bool tryDeleteArgument(size_t); + WriteBarrierBase<Unknown>& argument(size_t); + void allocateSlowArguments(); + + void init(CallFrame*); + + WriteBarrier<JSActivation> m_activation; + + unsigned m_numArguments; + + // We make these full byte booleans to make them easy to test from the JIT, + // and because even if they were single-bit booleans we still wouldn't save + // any space. + bool m_overrodeLength; + bool m_overrodeCallee; + bool m_overrodeCaller; + bool m_isStrictMode; + + WriteBarrierBase<Unknown>* m_registers; + OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; + + OwnArrayPtr<SlowArgument> m_slowArguments; + + WriteBarrier<JSFunction> m_callee; + }; + + Arguments* asArguments(JSValue); + + inline Arguments* asArguments(JSValue value) { - Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame); - arguments->finishCreation(callFrame); - return arguments; + ASSERT(asObject(value)->inherits(&Arguments::s_info)); + return static_cast<Arguments*>(asObject(value)); } - - static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame, InlineCallFrame* inlineCallFrame) + + inline Arguments::Arguments(CallFrame* callFrame) + : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) { - Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame); - arguments->finishCreation(callFrame, inlineCallFrame); - return arguments; } - enum { MaxArguments = 0x10000 }; + inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) + : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) + { + } -private: - enum NoParametersType { NoParameters }; - - Arguments(CallFrame*); - Arguments(CallFrame*, NoParametersType); - - void tearOffForInlineCallFrame(JSGlobalData& globalData, Register*, InlineCallFrame*); + inline void Arguments::allocateSlowArguments() + { + if (m_slowArguments) + return; + m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]); + for (size_t i = 0; i < m_numArguments; ++i) { + ASSERT(m_slowArguments[i].status == SlowArgument::Normal); + m_slowArguments[i].index = CallFrame::argumentOffset(i); + } + } -public: - static const ClassInfo s_info; + inline bool Arguments::tryDeleteArgument(size_t argument) + { + if (!isArgument(argument)) + return false; + allocateSlowArguments(); + m_slowArguments[argument].status = SlowArgument::Deleted; + return true; + } - static void visitChildren(JSCell*, SlotVisitor&); + inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value) + { + if (!isArgument(argument)) + return false; + this->argument(argument).set(globalData, this, value); + return true; + } - void fillArgList(ExecState*, MarkedArgumentBuffer&); + inline JSValue Arguments::tryGetArgument(size_t argument) + { + if (!isArgument(argument)) + return JSValue(); + return this->argument(argument).get(); + } - uint32_t length(ExecState* exec) const + inline bool Arguments::isDeletedArgument(size_t argument) { - if (UNLIKELY(m_overrodeLength)) - return get(exec, exec->propertyNames().length).toUInt32(exec); - return m_numArguments; + if (argument >= m_numArguments) + return false; + if (!m_slowArguments) + return false; + if (m_slowArguments[argument].status != SlowArgument::Deleted) + return false; + return true; } - - void copyToArguments(ExecState*, CallFrame*, uint32_t length); - void tearOff(CallFrame*); - void tearOff(CallFrame*, InlineCallFrame*); - bool isTornOff() const { return m_registerArray; } - void didTearOffActivation(ExecState*, JSActivation*); - - static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); + + inline bool Arguments::isArgument(size_t argument) + { + if (argument >= m_numArguments) + return false; + if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted) + return false; + return true; } - -protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; - - void finishCreation(CallFrame*); - void finishCreation(CallFrame*, InlineCallFrame*); - -private: - static void destroy(JSCell*); - static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); - static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&); - static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); - static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); - static bool deleteProperty(JSCell*, ExecState*, PropertyName); - static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); - static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); - void createStrictModeCallerIfNecessary(ExecState*); - void createStrictModeCalleeIfNecessary(ExecState*); - - bool isArgument(size_t); - bool trySetArgument(JSGlobalData&, size_t argument, JSValue); - JSValue tryGetArgument(size_t argument); - bool isDeletedArgument(size_t); - bool tryDeleteArgument(size_t); - WriteBarrierBase<Unknown>& argument(size_t); - void allocateSlowArguments(); - - void init(CallFrame*); - - WriteBarrier<JSActivation> m_activation; - - unsigned m_numArguments; - - // We make these full byte booleans to make them easy to test from the JIT, - // and because even if they were single-bit booleans we still wouldn't save - // any space. - bool m_overrodeLength; - bool m_overrodeCallee; - bool m_overrodeCaller; - bool m_isStrictMode; - - WriteBarrierBase<Unknown>* m_registers; - OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; - - OwnArrayPtr<SlowArgument> m_slowArguments; - - WriteBarrier<JSFunction> m_callee; -}; - -Arguments* asArguments(JSValue); - -inline Arguments* asArguments(JSValue value) -{ - ASSERT(asObject(value)->inherits(&Arguments::s_info)); - return static_cast<Arguments*>(asObject(value)); -} - -inline Arguments::Arguments(CallFrame* callFrame) - : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) -{ -} - -inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) - : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) -{ -} - -inline void Arguments::allocateSlowArguments() -{ - if (m_slowArguments) - return; - m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]); - for (size_t i = 0; i < m_numArguments; ++i) { - ASSERT(m_slowArguments[i].status == SlowArgument::Normal); - m_slowArguments[i].index = CallFrame::argumentOffset(i); + + inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument) + { + ASSERT(isArgument(argument)); + if (!m_slowArguments) + return m_registers[CallFrame::argumentOffset(argument)]; + + int index = m_slowArguments[argument].index; + if (!m_activation || m_slowArguments[argument].status != SlowArgument::Captured) + return m_registers[index]; + + return m_activation->registerAt(index); } -} - -inline bool Arguments::tryDeleteArgument(size_t argument) -{ - if (!isArgument(argument)) - return false; - allocateSlowArguments(); - m_slowArguments[argument].status = SlowArgument::Deleted; - return true; -} - -inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value) -{ - if (!isArgument(argument)) - return false; - this->argument(argument).set(globalData, this, value); - return true; -} - -inline JSValue Arguments::tryGetArgument(size_t argument) -{ - if (!isArgument(argument)) - return JSValue(); - return this->argument(argument).get(); -} - -inline bool Arguments::isDeletedArgument(size_t argument) -{ - if (argument >= m_numArguments) - return false; - if (!m_slowArguments) - return false; - if (m_slowArguments[argument].status != SlowArgument::Deleted) - return false; - return true; -} - -inline bool Arguments::isArgument(size_t argument) -{ - if (argument >= m_numArguments) - return false; - if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted) - return false; - return true; -} - -inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument) -{ - ASSERT(isArgument(argument)); - if (!m_slowArguments) - return m_registers[CallFrame::argumentOffset(argument)]; - - int index = m_slowArguments[argument].index; - if (!m_activation || m_slowArguments[argument].status != SlowArgument::Captured) - return m_registers[index]; - - return m_activation->registerAt(index); -} - -inline void Arguments::finishCreation(CallFrame* callFrame) -{ - Base::finishCreation(callFrame->globalData()); - ASSERT(inherits(&s_info)); - - JSFunction* callee = jsCast<JSFunction*>(callFrame->callee()); - m_numArguments = callFrame->argumentCount(); - m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()); - m_callee.set(callFrame->globalData(), this, callee); - m_overrodeLength = false; - m_overrodeCallee = false; - m_overrodeCaller = false; - m_isStrictMode = callFrame->codeBlock()->isStrictMode(); - - SharedSymbolTable* symbolTable = callFrame->codeBlock()->symbolTable(); - const SlowArgument* slowArguments = symbolTable->slowArguments(); - if (slowArguments) { - allocateSlowArguments(); - size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount()); - for (size_t i = 0; i < count; ++i) - m_slowArguments[i] = slowArguments[i]; + + inline void Arguments::finishCreation(CallFrame* callFrame) + { + Base::finishCreation(callFrame->globalData()); + ASSERT(inherits(&s_info)); + + JSFunction* callee = jsCast<JSFunction*>(callFrame->callee()); + m_numArguments = callFrame->argumentCount(); + m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()); + m_callee.set(callFrame->globalData(), this, callee); + m_overrodeLength = false; + m_overrodeCallee = false; + m_overrodeCaller = false; + m_isStrictMode = callFrame->codeBlock()->isStrictMode(); + + SharedSymbolTable* symbolTable = callFrame->codeBlock()->symbolTable(); + const SlowArgument* slowArguments = symbolTable->slowArguments(); + if (slowArguments) { + allocateSlowArguments(); + size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount()); + for (size_t i = 0; i < count; ++i) + m_slowArguments[i] = slowArguments[i]; + } + + // The bytecode generator omits op_tear_off_activation in cases of no + // declared parameters, so we need to tear off immediately. + if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) + tearOff(callFrame); } - // The bytecode generator omits op_tear_off_activation in cases of no - // declared parameters, so we need to tear off immediately. - if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) - tearOff(callFrame); -} - -inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame) -{ - Base::finishCreation(callFrame->globalData()); - ASSERT(inherits(&s_info)); - - JSFunction* callee = inlineCallFrame->callee.get(); - m_numArguments = inlineCallFrame->arguments.size() - 1; - m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset; - m_callee.set(callFrame->globalData(), this, callee); - m_overrodeLength = false; - m_overrodeCallee = false; - m_overrodeCaller = false; - m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode(); - ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments()); - - // The bytecode generator omits op_tear_off_activation in cases of no - // declared parameters, so we need to tear off immediately. - if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) - tearOff(callFrame, inlineCallFrame); -} + inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame) + { + Base::finishCreation(callFrame->globalData()); + ASSERT(inherits(&s_info)); + + JSFunction* callee = inlineCallFrame->callee.get(); + m_numArguments = inlineCallFrame->arguments.size() - 1; + m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset; + m_callee.set(callFrame->globalData(), this, callee); + m_overrodeLength = false; + m_overrodeCallee = false; + m_overrodeCaller = false; + m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode(); + ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)->slowArguments()); + + // The bytecode generator omits op_tear_off_activation in cases of no + // declared parameters, so we need to tear off immediately. + if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) + tearOff(callFrame, inlineCallFrame); + } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp index a3fce45f2..5c2cd7167 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -25,8 +25,8 @@ #include "ArrayConstructor.h" #include "ArrayPrototype.h" -#include "ButterflyInlines.h" -#include "CopiedSpaceInlines.h" +#include "ButterflyInlineMethods.h" +#include "CopiedSpaceInlineMethods.h" #include "Error.h" #include "ExceptionHelpers.h" #include "JSArray.h" @@ -77,15 +77,15 @@ bool ArrayConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exe // ------------------------------ Functions --------------------------- -JSObject* constructArrayWithSizeQuirk(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, JSValue length) +JSObject* constructArrayWithSizeQuirk(ExecState* exec, JSGlobalObject* globalObject, JSValue length) { if (!length.isNumber()) - return constructArray(exec, profile, globalObject, &length, 1); + return constructArray(exec, globalObject, &length, 1); uint32_t n = length.toUInt32(exec); if (n != length.toNumber(exec)) return throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))); - return constructEmptyArray(exec, profile, globalObject, n); + return constructEmptyArray(exec, globalObject, n); } static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) @@ -94,10 +94,10 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi // a single numeric argument denotes the array size (!) if (args.size() == 1) - return constructArrayWithSizeQuirk(exec, 0, globalObject, args.at(0)); + return constructArrayWithSizeQuirk(exec, globalObject, args.at(0)); // otherwise the array is constructed with the arguments in it - return constructArray(exec, 0, globalObject, args); + return constructArray(exec, globalObject, args); } static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec) diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h index 96860b0fc..dcbf0a1b3 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.h +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h @@ -25,42 +25,42 @@ namespace JSC { -class ArrayPrototype; -class JSArray; + class ArrayPrototype; + class JSArray; -class ArrayConstructor : public InternalFunction { -public: - typedef InternalFunction Base; + class ArrayConstructor : public InternalFunction { + public: + typedef InternalFunction Base; - static ArrayConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ArrayPrototype* arrayPrototype) - { - ArrayConstructor* constructor = new (NotNull, allocateCell<ArrayConstructor>(*exec->heap())) ArrayConstructor(globalObject, structure); - constructor->finishCreation(exec, arrayPrototype); - return constructor; - } + static ArrayConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ArrayPrototype* arrayPrototype) + { + ArrayConstructor* constructor = new (NotNull, allocateCell<ArrayConstructor>(*exec->heap())) ArrayConstructor(globalObject, structure); + constructor->finishCreation(exec, arrayPrototype); + return constructor; + } - static const ClassInfo s_info; + static const ClassInfo s_info; - static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); - } + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); + } -protected: - void finishCreation(ExecState*, ArrayPrototype*); - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; + protected: + void finishCreation(ExecState*, ArrayPrototype*); + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; -private: - ArrayConstructor(JSGlobalObject*, Structure*); - static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); + private: + ArrayConstructor(JSGlobalObject*, Structure*); + static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); - static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); + static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); - static ConstructType getConstructData(JSCell*, ConstructData&); - static CallType getCallData(JSCell*, CallData&); -}; + static ConstructType getConstructData(JSCell*, ConstructData&); + static CallType getCallData(JSCell*, CallData&); + }; -JSObject* constructArrayWithSizeQuirk(ExecState*, ArrayAllocationProfile*, JSGlobalObject*, JSValue); + JSObject* constructArrayWithSizeQuirk(ExecState*, JSGlobalObject*, JSValue); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index cc847d8ff..6975dc778 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -24,10 +24,10 @@ #include "config.h" #include "ArrayPrototype.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" #include "CachedCall.h" #include "CodeBlock.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "Interpreter.h" #include "JIT.h" #include "JSStringBuilder.h" @@ -456,7 +456,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); - JSArray* arr = constructEmptyArray(exec, 0); + JSArray* arr = constructEmptyArray(exec); unsigned n = 0; JSValue curArg = thisValue.toObject(exec); if (exec->hadException()) @@ -618,7 +618,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec) return JSValue::encode(jsUndefined()); // We return a new array - JSArray* resObj = constructEmptyArray(exec, 0); + JSArray* resObj = constructEmptyArray(exec); JSValue result = resObj; unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); @@ -733,7 +733,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) return JSValue::encode(jsUndefined()); if (!exec->argumentCount()) - return JSValue::encode(constructEmptyArray(exec, 0)); + return JSValue::encode(constructEmptyArray(exec)); unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); @@ -748,7 +748,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) deleteCount = static_cast<unsigned>(deleteDouble); } - JSArray* resObj = JSArray::tryCreateUninitialized(exec->globalData(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount); + JSArray* resObj = JSArray::tryCreateUninitialized(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), deleteCount); if (!resObj) return JSValue::encode(throwOutOfMemoryError(exec)); @@ -820,7 +820,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec) return throwVMTypeError(exec); JSValue applyThis = exec->argument(1); - JSArray* resultArray = constructEmptyArray(exec, 0); + JSArray* resultArray = constructEmptyArray(exec); unsigned filterIndex = 0; unsigned k = 0; @@ -880,7 +880,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec) JSValue applyThis = exec->argument(1); - JSArray* resultArray = constructEmptyArray(exec, 0, length); + JSArray* resultArray = constructEmptyArray(exec, length); unsigned k = 0; if (callType == CallTypeJS && isJSArray(thisObj)) { JSFunction* f = jsCast<JSFunction*>(function); diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h index 2b83d39b7..b33021121 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.h +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h @@ -26,28 +26,28 @@ namespace JSC { -class ArrayPrototype : public JSArray { -private: - ArrayPrototype(JSGlobalObject*, Structure*, Butterfly*); + class ArrayPrototype : public JSArray { + private: + ArrayPrototype(JSGlobalObject*, Structure*, Butterfly*); -public: - typedef JSArray Base; + public: + typedef JSArray Base; - static ArrayPrototype* create(ExecState*, JSGlobalObject*, Structure*); + static ArrayPrototype* create(ExecState*, JSGlobalObject*, Structure*); - static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); - static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); + static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); + static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); - static const ClassInfo s_info; + static const ClassInfo s_info; - static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithArrayStorage); - } + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithArrayStorage); + } -protected: - void finishCreation(JSGlobalObject*); -}; + protected: + void finishCreation(JSGlobalObject*); + }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h index 4b8d53f7e..cb93aea8a 100644 --- a/Source/JavaScriptCore/runtime/Butterfly.h +++ b/Source/JavaScriptCore/runtime/Butterfly.h @@ -88,18 +88,12 @@ public: template<typename T> T* indexingPayload() { return reinterpret_cast<T*>(this); } ArrayStorage* arrayStorage() { return indexingPayload<ArrayStorage>(); } - WriteBarrier<Unknown>* contiguousInt32() { return indexingPayload<WriteBarrier<Unknown> >(); } - double* contiguousDouble() { return indexingPayload<double>(); } WriteBarrier<Unknown>* contiguous() { return indexingPayload<WriteBarrier<Unknown> >(); } static Butterfly* fromContiguous(WriteBarrier<Unknown>* contiguous) { return reinterpret_cast<Butterfly*>(contiguous); } - static Butterfly* fromContiguous(double* contiguous) - { - return reinterpret_cast<Butterfly*>(contiguous); - } static ptrdiff_t offsetOfPropertyStorage() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); } static int indexOfPropertyStorage() diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h index 9167497a4..86a836bef 100644 --- a/Source/JavaScriptCore/runtime/ButterflyInlines.h +++ b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h @@ -23,12 +23,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ButterflyInlines_h -#define ButterflyInlines_h +#ifndef ButterflyInlineMethods_h +#define ButterflyInlineMethods_h #include "ArrayStorage.h" #include "Butterfly.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "CopyVisitor.h" #include "JSGlobalData.h" #include "Structure.h" @@ -61,9 +61,8 @@ inline Butterfly* Butterfly::create(JSGlobalData& globalData, Structure* structu inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) { - size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); Butterfly* result = fromBase( - visitor.allocateNewSpace(size), + visitor.allocateNewSpace(totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)), preCapacity, propertyCapacity); return result; } @@ -176,5 +175,5 @@ inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) } // namespace JSC -#endif // ButterflyInlines_h +#endif // ButterflyInlineMethods_h diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp index 068919528..4de760e49 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.cpp +++ b/Source/JavaScriptCore/runtime/CodeCache.cpp @@ -36,6 +36,7 @@ namespace JSC { CodeCache::CodeCache() + : m_randomGenerator(static_cast<uint32_t>(randomNumber() * UINT32_MAX)) { } @@ -66,9 +67,9 @@ UnlinkedCodeBlockType* CodeCache::getCodeBlock(JSGlobalData& globalData, Executa CodeBlockKey key = makeCodeBlockKey(source, CacheTypes<UnlinkedCodeBlockType>::codeType, strictness); bool storeInCache = false; if (debuggerMode == DebuggerOff && profilerMode == ProfilerOff) { - const Strong<UnlinkedCodeBlock>* result = m_cachedCodeBlocks.find(key); - if (result) { - UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(result->get()); + CodeBlockIndicesMap::iterator result = m_cachedCodeBlockIndices.find(key); + if (result != m_cachedCodeBlockIndices.end()) { + UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(m_cachedCodeBlocks[result->value].second.get()); unsigned firstLine = source.firstLine() + unlinkedCode->firstLine(); executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount()); return unlinkedCode; @@ -90,8 +91,14 @@ UnlinkedCodeBlockType* CodeCache::getCodeBlock(JSGlobalData& globalData, Executa if (error.m_type != ParserError::ErrorNone) return 0; - if (storeInCache) - m_cachedCodeBlocks.add(key, Strong<UnlinkedCodeBlock>(globalData, unlinkedCode)); + if (storeInCache) { + size_t index = m_randomGenerator.getUint32() % kMaxCodeBlockEntries; + if (m_cachedCodeBlocks[index].second) + m_cachedCodeBlockIndices.remove(m_cachedCodeBlocks[index].first); + m_cachedCodeBlockIndices.set(key, index); + m_cachedCodeBlocks[index].second.set(globalData, unlinkedCode); + m_cachedCodeBlocks[index].first = key; + } return unlinkedCode; } @@ -126,7 +133,6 @@ UnlinkedFunctionCodeBlock* CodeCache::generateFunctionCodeBlock(JSGlobalData& gl body->destroyData(); if (error.m_type != ParserError::ErrorNone) return 0; - m_cachedFunctionCode.add(result, Strong<UnlinkedFunctionCodeBlock>(globalData, result)); return result; } @@ -143,9 +149,9 @@ CodeCache::GlobalFunctionKey CodeCache::makeGlobalFunctionKey(const SourceCode& UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, ParserError& error) { GlobalFunctionKey key = makeGlobalFunctionKey(source, name.string()); - const Strong<UnlinkedFunctionExecutable>* result = m_cachedGlobalFunctions.find(key); - if (result) - return result->get(); + GlobalFunctionIndicesMap::iterator result = m_cachedGlobalFunctionIndices.find(key); + if (result != m_cachedGlobalFunctionIndices.end()) + return m_cachedGlobalFunctions[result->value].second.get(); RefPtr<ProgramNode> program = parse<ProgramNode>(&globalData, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error); if (!program) { @@ -167,13 +173,14 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlo UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&globalData, source, body); functionExecutable->m_nameValue.set(globalData, functionExecutable, jsString(&globalData, name.string())); - m_cachedGlobalFunctions.add(key, Strong<UnlinkedFunctionExecutable>(globalData, functionExecutable)); - return functionExecutable; -} + size_t index = m_randomGenerator.getUint32() % kMaxGlobalFunctionEntries; + if (m_cachedGlobalFunctions[index].second) + m_cachedGlobalFunctionIndices.remove(m_cachedGlobalFunctions[index].first); + m_cachedGlobalFunctionIndices.set(key, index); + m_cachedGlobalFunctions[index].second.set(globalData, functionExecutable); + m_cachedGlobalFunctions[index].first = key; -void CodeCache::usedFunctionCode(JSGlobalData& globalData, UnlinkedFunctionCodeBlock* codeBlock) -{ - m_cachedFunctionCode.add(codeBlock, Strong<UnlinkedFunctionCodeBlock>(globalData, codeBlock)); + return functionExecutable; } } diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h index 740aaa6df..4d4617189 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.h +++ b/Source/JavaScriptCore/runtime/CodeCache.h @@ -34,7 +34,6 @@ #include <wtf/FixedArray.h> #include <wtf/Forward.h> #include <wtf/PassOwnPtr.h> -#include <wtf/RandomNumber.h> #include <wtf/text/WTFString.h> namespace JSC { @@ -52,41 +51,6 @@ struct ParserError; class SourceCode; class SourceProvider; -template <typename KeyType, typename EntryType, int CacheSize> class Thingy { - typedef typename HashMap<KeyType, unsigned>::iterator iterator; -public: - Thingy() - : m_randomGenerator((static_cast<uint32_t>(randomNumber() * UINT32_MAX))) - { - } - const EntryType* find(const KeyType& key) - { - iterator result = m_map.find(key); - if (result == m_map.end()) - return 0; - return &m_data[result->value].second; - } - void add(const KeyType& key, const EntryType& value) - { - iterator result = m_map.find(key); - if (result != m_map.end()) { - m_data[result->value].second = value; - return; - } - size_t newIndex = m_randomGenerator.getUint32() % CacheSize; - if (m_data[newIndex].second) - m_map.remove(m_data[newIndex].first); - m_map.add(key, newIndex); - m_data[newIndex].first = key; - m_data[newIndex].second = value; - ASSERT(m_map.size() <= CacheSize); - } -private: - HashMap<KeyType, unsigned> m_map; - FixedArray<std::pair<KeyType, EntryType>, CacheSize> m_data; - WeakRandom m_randomGenerator; -}; - class CodeCache { public: static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); } @@ -95,12 +59,13 @@ public: UnlinkedEvalCodeBlock* getEvalCodeBlock(JSGlobalData&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&); UnlinkedFunctionCodeBlock* getFunctionCodeBlock(JSGlobalData&, UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&); UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(JSGlobalData&, const Identifier&, const SourceCode&, ParserError&); - void usedFunctionCode(JSGlobalData&, UnlinkedFunctionCodeBlock*); ~CodeCache(); enum CodeType { EvalType, ProgramType, FunctionType }; typedef std::pair<String, unsigned> CodeBlockKey; + typedef HashMap<CodeBlockKey, unsigned> CodeBlockIndicesMap; typedef std::pair<String, String> GlobalFunctionKey; + typedef HashMap<GlobalFunctionKey, unsigned> GlobalFunctionIndicesMap; private: CodeCache(); @@ -109,17 +74,18 @@ private: template <class UnlinkedCodeBlockType, class ExecutableType> inline UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&); CodeBlockKey makeCodeBlockKey(const SourceCode&, CodeType, JSParserStrictness); + CodeBlockIndicesMap m_cachedCodeBlockIndices; GlobalFunctionKey makeGlobalFunctionKey(const SourceCode&, const String&); + GlobalFunctionIndicesMap m_cachedGlobalFunctionIndices; enum { kMaxCodeBlockEntries = 1024, - kMaxGlobalFunctionEntries = 1024, - kMaxFunctionCodeBlocks = 1024 + kMaxGlobalFunctionEntries = 1024 }; - Thingy<CodeBlockKey, Strong<UnlinkedCodeBlock>, kMaxCodeBlockEntries> m_cachedCodeBlocks; - Thingy<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable>, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions; - Thingy<UnlinkedFunctionCodeBlock*, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_cachedFunctionCode; + FixedArray<std::pair<CodeBlockKey, Strong<UnlinkedCodeBlock> >, kMaxCodeBlockEntries> m_cachedCodeBlocks; + FixedArray<std::pair<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable> >, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions; + WeakRandom m_randomGenerator; }; } diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp index 49a0e256d..20a2e2acb 100644 --- a/Source/JavaScriptCore/runtime/Executable.cpp +++ b/Source/JavaScriptCore/runtime/Executable.cpp @@ -620,17 +620,18 @@ void FunctionExecutable::clearCodeIfNotCompiling() clearCode(); } -void FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling() +void FunctionExecutable::clearUnlinkedCodeIfNotCompiling() { if (isCompiling()) return; - m_unlinkedExecutable->clearCodeForRecompilation(); + m_unlinkedExecutable->clearCode(); } void FunctionExecutable::clearCode() { m_codeBlockForCall.clear(); m_codeBlockForConstruct.clear(); + m_unlinkedExecutable->clearCode(); Base::clearCode(); } diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h index 98471b85b..74b4add75 100644 --- a/Source/JavaScriptCore/runtime/Executable.h +++ b/Source/JavaScriptCore/runtime/Executable.h @@ -704,7 +704,7 @@ namespace JSC { SharedSymbolTable* symbolTable(CodeSpecializationKind kind) const { return m_unlinkedExecutable->symbolTable(kind); } void clearCodeIfNotCompiling(); - void clearUnlinkedCodeForRecompilationIfNotCompiling(); + void clearUnlinkedCodeIfNotCompiling(); static void visitChildren(JSCell*, SlotVisitor&); static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp index 8e4390b1b..a4b2202c1 100644 --- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp +++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp @@ -186,7 +186,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec) // Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order. size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0; - JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), numBoundArgs); + JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructure(), numBoundArgs); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(exec)); diff --git a/Source/JavaScriptCore/runtime/IndexingHeaderInlines.h b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h index cfad1c8c2..22785ce24 100644 --- a/Source/JavaScriptCore/runtime/IndexingHeaderInlines.h +++ b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef IndexingHeaderInlines_h -#define IndexingHeaderInlines_h +#ifndef IndexingHeaderInlineMethods_h +#define IndexingHeaderInlineMethods_h #include "ArrayStorage.h" #include "IndexingHeader.h" @@ -43,9 +43,6 @@ inline size_t IndexingHeader::preCapacity(Structure* structure) inline size_t IndexingHeader::indexingPayloadSizeInBytes(Structure* structure) { switch (structure->indexingType()) { - case ALL_UNDECIDED_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return vectorLength() * sizeof(EncodedJSValue); @@ -60,5 +57,5 @@ inline size_t IndexingHeader::indexingPayloadSizeInBytes(Structure* structure) } // namespace JSC -#endif // IndexingHeaderInlines_h +#endif // IndexingHeaderInlineMethods_h diff --git a/Source/JavaScriptCore/runtime/IndexingType.cpp b/Source/JavaScriptCore/runtime/IndexingType.cpp index dc2733ad1..7261847a2 100644 --- a/Source/JavaScriptCore/runtime/IndexingType.cpp +++ b/Source/JavaScriptCore/runtime/IndexingType.cpp @@ -31,46 +31,6 @@ namespace JSC { -IndexingType leastUpperBoundOfIndexingTypes(IndexingType a, IndexingType b) -{ - // It doesn't make sense to LUB something that is an array with something that isn't. - ASSERT((a & IsArray) == (b & IsArray)); - - // Boy, this sure is easy right now. - return std::max(a, b); -} - -IndexingType leastUpperBoundOfIndexingTypeAndType(IndexingType indexingType, SpeculatedType type) -{ - if (!type) - return indexingType; - switch (indexingType) { - case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - if (isInt32Speculation(type)) - return (indexingType & ~IndexingShapeMask) | Int32Shape; - if (isNumberSpeculation(type)) - return (indexingType & ~IndexingShapeMask) | DoubleShape; - return (indexingType & ~IndexingShapeMask) | ContiguousShape; - case ALL_DOUBLE_INDEXING_TYPES: - if (isNumberSpeculation(type)) - return indexingType; - return (indexingType & ~IndexingShapeMask) | ContiguousShape; - case ALL_CONTIGUOUS_INDEXING_TYPES: - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return indexingType; - default: - CRASH(); - return 0; - } -} - -IndexingType leastUpperBoundOfIndexingTypeAndValue(IndexingType indexingType, JSValue value) -{ - return leastUpperBoundOfIndexingTypeAndType(indexingType, speculationFromValue(value)); -} - const char* indexingTypeToString(IndexingType indexingType) { static char result[128]; @@ -79,12 +39,6 @@ const char* indexingTypeToString(IndexingType indexingType) case NonArray: basicName = "NonArray"; break; - case NonArrayWithInt32: - basicName = "NonArrayWithInt32"; - break; - case NonArrayWithDouble: - basicName = "NonArrayWithDouble"; - break; case NonArrayWithContiguous: basicName = "NonArrayWithContiguous"; break; @@ -97,15 +51,6 @@ const char* indexingTypeToString(IndexingType indexingType) case ArrayClass: basicName = "ArrayClass"; break; - case ArrayWithUndecided: - basicName = "ArrayWithUndecided"; - break; - case ArrayWithInt32: - basicName = "ArrayWithInt32"; - break; - case ArrayWithDouble: - basicName = "ArrayWithDouble"; - break; case ArrayWithContiguous: basicName = "ArrayWithContiguous"; break; diff --git a/Source/JavaScriptCore/runtime/IndexingType.h b/Source/JavaScriptCore/runtime/IndexingType.h index ab253be1e..4bbe3cfa0 100644 --- a/Source/JavaScriptCore/runtime/IndexingType.h +++ b/Source/JavaScriptCore/runtime/IndexingType.h @@ -26,7 +26,6 @@ #ifndef IndexingType_h #define IndexingType_h -#include "SpeculatedType.h" #include <wtf/StdLibExtras.h> namespace JSC { @@ -38,32 +37,21 @@ static const IndexingType IsArray = 1; // The shape of the indexed property storage. static const IndexingType IndexingShapeMask = 30; -static const IndexingType NoIndexingShape = 0; -static const IndexingType UndecidedShape = 2; // Only useful for arrays. -static const IndexingType Int32Shape = 20; -static const IndexingType DoubleShape = 22; +static const IndexingType NoIndexingShape = 0; static const IndexingType ContiguousShape = 26; static const IndexingType ArrayStorageShape = 28; static const IndexingType SlowPutArrayStorageShape = 30; -static const IndexingType IndexingShapeShift = 1; -static const IndexingType NumberOfIndexingShapes = 16; - // Additional flags for tracking the history of the type. These are usually // masked off unless you ask for them directly. static const IndexingType MayHaveIndexedAccessors = 32; // List of acceptable array types. static const IndexingType NonArray = 0; -static const IndexingType NonArrayWithInt32 = Int32Shape; -static const IndexingType NonArrayWithDouble = DoubleShape; static const IndexingType NonArrayWithContiguous = ContiguousShape; static const IndexingType NonArrayWithArrayStorage = ArrayStorageShape; static const IndexingType NonArrayWithSlowPutArrayStorage = SlowPutArrayStorageShape; static const IndexingType ArrayClass = IsArray; // I'd want to call this "Array" but this would lead to disastrous namespace pollution. -static const IndexingType ArrayWithUndecided = IsArray | UndecidedShape; -static const IndexingType ArrayWithInt32 = IsArray | Int32Shape; -static const IndexingType ArrayWithDouble = IsArray | DoubleShape; static const IndexingType ArrayWithContiguous = IsArray | ContiguousShape; static const IndexingType ArrayWithArrayStorage = IsArray | ArrayStorageShape; static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArrayStorageShape; @@ -72,17 +60,6 @@ static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArr NonArray: \ case ArrayClass -#define ALL_UNDECIDED_INDEXING_TYPES \ - ArrayWithUndecided - -#define ALL_INT32_INDEXING_TYPES \ - NonArrayWithInt32: \ - case ArrayWithInt32 - -#define ALL_DOUBLE_INDEXING_TYPES \ - NonArrayWithDouble: \ - case ArrayWithDouble - #define ALL_CONTIGUOUS_INDEXING_TYPES \ NonArrayWithContiguous: \ case ArrayWithContiguous @@ -106,21 +83,6 @@ static inline bool hasIndexingHeader(IndexingType type) return hasIndexedProperties(type); } -static inline bool hasUndecided(IndexingType indexingType) -{ - return (indexingType & IndexingShapeMask) == UndecidedShape; -} - -static inline bool hasInt32(IndexingType indexingType) -{ - return (indexingType & IndexingShapeMask) == Int32Shape; -} - -static inline bool hasDouble(IndexingType indexingType) -{ - return (indexingType & IndexingShapeMask) == DoubleShape; -} - static inline bool hasContiguous(IndexingType indexingType) { return (indexingType & IndexingShapeMask) == ContiguousShape; @@ -143,12 +105,6 @@ static inline bool shouldUseSlowPut(IndexingType indexingType) return (indexingType & IndexingShapeMask) == SlowPutArrayStorageShape; } -// Return an indexing type that can handle all of the elements of both indexing types. -IndexingType leastUpperBoundOfIndexingTypes(IndexingType, IndexingType); - -IndexingType leastUpperBoundOfIndexingTypeAndType(IndexingType, SpeculatedType); -IndexingType leastUpperBoundOfIndexingTypeAndValue(IndexingType, JSValue); - const char* indexingTypeToString(IndexingType); // Mask of all possible types. diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h index b8f5621af..fc6336463 100644 --- a/Source/JavaScriptCore/runtime/JSActivation.h +++ b/Source/JavaScriptCore/runtime/JSActivation.h @@ -30,7 +30,7 @@ #define JSActivation_h #include "CodeBlock.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "JSVariableObject.h" #include "Nodes.h" #include "SymbolTable.h" diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp index 4ba5cc2bd..d1ece1a36 100644 --- a/Source/JavaScriptCore/runtime/JSArray.cpp +++ b/Source/JavaScriptCore/runtime/JSArray.cpp @@ -24,14 +24,14 @@ #include "JSArray.h" #include "ArrayPrototype.h" -#include "ButterflyInlines.h" -#include "CachedCall.h" +#include "ButterflyInlineMethods.h" #include "CopiedSpace.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" +#include "CachedCall.h" #include "Error.h" #include "Executable.h" #include "GetterSetter.h" -#include "IndexingHeaderInlines.h" +#include "IndexingHeaderInlineMethods.h" #include "PropertyNameArray.h" #include "Reject.h" #include <wtf/AVLTree.h> @@ -410,33 +410,25 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException exec, newLength, throwException, convertContiguousToArrayStorage(exec->globalData())); } - createInitialUndecided(exec->globalData(), newLength); + createInitialContiguous(exec->globalData(), newLength); return true; - case ArrayWithUndecided: - case ArrayWithInt32: - case ArrayWithDouble: case ArrayWithContiguous: if (newLength == m_butterfly->publicLength()) return true; if (newLength >= MAX_ARRAY_INDEX // This case ensures that we can do fast push. || (newLength >= MIN_SPARSE_ARRAY_INDEX - && !isDenseEnoughForVector(newLength, countElements()))) { + && !isDenseEnoughForVector(newLength, countElementsInContiguous(m_butterfly)))) { return setLengthWithArrayStorage( exec, newLength, throwException, - ensureArrayStorage(exec->globalData())); + convertContiguousToArrayStorage(exec->globalData())); } if (newLength > m_butterfly->publicLength()) { - ensureLength(exec->globalData(), newLength); + ensureContiguousLength(exec->globalData(), newLength); return true; } - if (structure()->indexingType() == ArrayWithDouble) { - for (unsigned i = m_butterfly->publicLength(); i-- > newLength;) - m_butterfly->contiguousDouble()[i] = QNaN; - } else { - for (unsigned i = m_butterfly->publicLength(); i-- > newLength;) - m_butterfly->contiguous()[i].clear(); - } + for (unsigned i = m_butterfly->publicLength(); i-- > newLength;) + m_butterfly->contiguous()[i].clear(); m_butterfly->setPublicLength(newLength); return true; @@ -456,13 +448,6 @@ JSValue JSArray::pop(ExecState* exec) case ArrayClass: return jsUndefined(); - case ArrayWithUndecided: - if (!m_butterfly->publicLength()) - return jsUndefined(); - // We have nothing but holes. So, drop down to the slow version. - break; - - case ArrayWithInt32: case ArrayWithContiguous: { unsigned length = m_butterfly->publicLength(); @@ -479,22 +464,6 @@ JSValue JSArray::pop(ExecState* exec) break; } - case ArrayWithDouble: { - unsigned length = m_butterfly->publicLength(); - - if (!length--) - return jsUndefined(); - - ASSERT(length < m_butterfly->vectorLength()); - double value = m_butterfly->contiguousDouble()[length]; - if (value == value) { - m_butterfly->contiguousDouble()[length] = QNaN; - m_butterfly->setPublicLength(length); - return JSValue(JSValue::EncodeAsDouble, value); - } - break; - } - case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); @@ -549,42 +518,10 @@ void JSArray::push(ExecState* exec, JSValue value) { switch (structure()->indexingType()) { case ArrayClass: { - createInitialUndecided(exec->globalData(), 0); - // Fall through. - } - - case ArrayWithUndecided: { - convertUndecidedForValue(exec->globalData(), value); - push(exec, value); - return; + putByIndexBeyondVectorLengthWithArrayStorage(exec, 0, value, true, createInitialArrayStorage(exec->globalData())); + break; } - case ArrayWithInt32: { - if (!value.isInt32()) { - convertInt32ForValue(exec->globalData(), value); - push(exec, value); - return; - } - - unsigned length = m_butterfly->publicLength(); - ASSERT(length <= m_butterfly->vectorLength()); - if (length < m_butterfly->vectorLength()) { - m_butterfly->contiguousInt32()[length].setWithoutWriteBarrier(value); - m_butterfly->setPublicLength(length + 1); - return; - } - - if (length > MAX_ARRAY_INDEX) { - methodTable()->putByIndex(this, exec, length, value, true); - if (!exec->hadException()) - throwError(exec, createRangeError(exec, "Invalid array length")); - return; - } - - putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, length, value); - return; - } - case ArrayWithContiguous: { unsigned length = m_butterfly->publicLength(); ASSERT(length <= m_butterfly->vectorLength()); @@ -601,42 +538,10 @@ void JSArray::push(ExecState* exec, JSValue value) return; } - putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, length, value); + putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, length, value); return; } - case ArrayWithDouble: { - if (!value.isNumber()) { - convertDoubleToContiguous(exec->globalData()); - push(exec, value); - return; - } - double valueAsDouble = value.asNumber(); - if (valueAsDouble != valueAsDouble) { - convertDoubleToContiguous(exec->globalData()); - push(exec, value); - return; - } - - unsigned length = m_butterfly->publicLength(); - ASSERT(length <= m_butterfly->vectorLength()); - if (length < m_butterfly->vectorLength()) { - m_butterfly->contiguousDouble()[length] = valueAsDouble; - m_butterfly->setPublicLength(length + 1); - return; - } - - if (length > MAX_ARRAY_INDEX) { - methodTable()->putByIndex(this, exec, length, value, true); - if (!exec->hadException()) - throwError(exec, createRangeError(exec, "Invalid array length")); - return; - } - - putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, length, value); - break; - } - case ArrayWithSlowPutArrayStorage: { unsigned oldLength = length(); if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true)) { @@ -742,11 +647,6 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex case ArrayClass: return true; - case ArrayWithUndecided: - // Don't handle this because it's confusing and it shouldn't come up. - return false; - - case ArrayWithInt32: case ArrayWithContiguous: { unsigned oldLength = m_butterfly->publicLength(); ASSERT(count <= oldLength); @@ -754,7 +654,7 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex // We may have to walk the entire array to do the shift. We're willing to do // so only if it's not horribly slow. if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX) - return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData())); + return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData())); unsigned end = oldLength - count; for (unsigned i = startIndex; i < end; ++i) { @@ -768,7 +668,7 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex // about holes (at least for now), but it can detect them quickly. So // we convert to array storage and then allow the array storage path to // figure it out. - return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData())); + return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData())); } // No need for a barrier since we're just moving data around in the same vector. // This is in line with our standing assumption that we won't have a deletion @@ -782,41 +682,6 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex return true; } - case ArrayWithDouble: { - unsigned oldLength = m_butterfly->publicLength(); - ASSERT(count <= oldLength); - - // We may have to walk the entire array to do the shift. We're willing to do - // so only if it's not horribly slow. - if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX) - return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData())); - - unsigned end = oldLength - count; - for (unsigned i = startIndex; i < end; ++i) { - // Storing to a hole is fine since we're still having a good time. But reading - // from a hole is totally not fine, since we might have to read from the proto - // chain. - double v = m_butterfly->contiguousDouble()[i + count]; - if (UNLIKELY(v != v)) { - // The purpose of this path is to ensure that we don't make the same - // mistake in the future: shiftCountWithArrayStorage() can't do anything - // about holes (at least for now), but it can detect them quickly. So - // we convert to array storage and then allow the array storage path to - // figure it out. - return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData())); - } - // No need for a barrier since we're just moving data around in the same vector. - // This is in line with our standing assumption that we won't have a deletion - // barrier. - m_butterfly->contiguousDouble()[i] = v; - } - for (unsigned i = end; i < oldLength; ++i) - m_butterfly->contiguousDouble()[i] = QNaN; - - m_butterfly->setPublicLength(oldLength - count); - return true; - } - case ArrayWithArrayStorage: case ArrayWithSlowPutArrayStorage: return shiftCountWithArrayStorage(startIndex, count, arrayStorage()); @@ -875,25 +740,23 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd { switch (structure()->indexingType()) { case ArrayClass: - case ArrayWithUndecided: // We could handle this. But it shouldn't ever come up, so we won't. return false; - - case ArrayWithInt32: + case ArrayWithContiguous: { unsigned oldLength = m_butterfly->publicLength(); // We may have to walk the entire array to do the unshift. We're willing to do so // only if it's not horribly slow. if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX) - return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData())); + return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData())); - ensureLength(exec->globalData(), oldLength + count); + ensureContiguousLength(exec->globalData(), oldLength + count); for (unsigned i = oldLength; i-- > startIndex;) { JSValue v = m_butterfly->contiguous()[i].get(); if (UNLIKELY(!v)) - return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData())); + return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData())); m_butterfly->contiguous()[i + count].setWithoutWriteBarrier(v); } @@ -905,31 +768,6 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd return true; } - case ArrayWithDouble: { - unsigned oldLength = m_butterfly->publicLength(); - - // We may have to walk the entire array to do the unshift. We're willing to do so - // only if it's not horribly slow. - if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX) - return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData())); - - ensureLength(exec->globalData(), oldLength + count); - - for (unsigned i = oldLength; i-- > startIndex;) { - double v = m_butterfly->contiguousDouble()[i]; - if (UNLIKELY(v != v)) - return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData())); - m_butterfly->contiguousDouble()[i + count] = v; - } - - // NOTE: we're leaving being garbage in the part of the array that we shifted out - // of. This is fine because the caller is required to store over that area, and - // in contiguous mode storing into a hole is guaranteed to behave exactly the same - // as storing over an existing element. - - return true; - } - case ArrayWithArrayStorage: case ArrayWithSlowPutArrayStorage: return unshiftCountWithArrayStorage(exec, startIndex, count, arrayStorage()); @@ -940,20 +778,6 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd } } -static int compareNumbersForQSortWithInt32(const void* a, const void* b) -{ - int32_t ia = static_cast<const JSValue*>(a)->asInt32(); - int32_t ib = static_cast<const JSValue*>(b)->asInt32(); - return ia - ib; -} - -static int compareNumbersForQSortWithDouble(const void* a, const void* b) -{ - double da = *static_cast<const double*>(a); - double db = *static_cast<const double*>(b); - return (da > db) - (da < db); -} - static int compareNumbersForQSort(const void* a, const void* b) { double da = static_cast<const JSValue*>(a)->asNumber(); @@ -971,7 +795,7 @@ static int compareByStringPairForQSort(const void* a, const void* b) template<IndexingType indexingType> void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) { - ASSERT(indexingType == ArrayWithInt32 || indexingType == ArrayWithDouble || indexingType == ArrayWithContiguous || indexingType == ArrayWithArrayStorage); + ASSERT(indexingType == ArrayWithContiguous || indexingType == ArrayWithArrayStorage); unsigned lengthNotIncludingUndefined; unsigned newRelevantLength; @@ -990,19 +814,11 @@ void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallTy return; bool allValuesAreNumbers = true; - switch (indexingType) { - case ArrayWithInt32: - case ArrayWithDouble: - break; - - default: - for (size_t i = 0; i < newRelevantLength; ++i) { - if (!data[i].isNumber()) { - allValuesAreNumbers = false; - break; - } + for (size_t i = 0; i < newRelevantLength; ++i) { + if (!data[i].isNumber()) { + allValuesAreNumbers = false; + break; } - break; } if (!allValuesAreNumbers) @@ -1011,23 +827,7 @@ void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallTy // For numeric comparison, which is fast, qsort is faster than mergesort. We // also don't require mergesort's stability, since there's no user visible // side-effect from swapping the order of equal primitive values. - int (*compare)(const void*, const void*); - switch (indexingType) { - case ArrayWithInt32: - compare = compareNumbersForQSortWithInt32; - break; - - case ArrayWithDouble: - compare = compareNumbersForQSortWithDouble; - ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(double)); - break; - - default: - compare = compareNumbersForQSort; - break; - } - - qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compare); + qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort); return; } @@ -1039,14 +839,6 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal case ArrayClass: return; - case ArrayWithInt32: - sortNumericVector<ArrayWithInt32>(exec, compareFunction, callType, callData); - break; - - case ArrayWithDouble: - sortNumericVector<ArrayWithDouble>(exec, compareFunction, callType, callData); - break; - case ArrayWithContiguous: sortNumericVector<ArrayWithContiguous>(exec, compareFunction, callType, callData); return; @@ -1062,7 +854,7 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal } template<IndexingType indexingType> -void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevantLength) +void JSArray::sortCompactedVector(ExecState* exec, WriteBarrier<Unknown>* begin, unsigned relevantLength) { if (!relevantLength) return; @@ -1083,31 +875,11 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan Heap::heap(this)->pushTempSortVector(&values); bool isSortingPrimitiveValues = true; - switch (indexingType) { - case ArrayWithInt32: - for (size_t i = 0; i < relevantLength; i++) { - JSValue value = static_cast<WriteBarrier<Unknown>*>(begin)[i].get(); - ASSERT(value.isInt32()); - values[i].first = value; - } - break; - - case ArrayWithDouble: - for (size_t i = 0; i < relevantLength; i++) { - double value = static_cast<double*>(begin)[i]; - ASSERT(value == value); - values[i].first = JSValue(JSValue::EncodeAsDouble, value); - } - break; - - default: - for (size_t i = 0; i < relevantLength; i++) { - JSValue value = static_cast<WriteBarrier<Unknown>*>(begin)[i].get(); - ASSERT(!value.isUndefined()); - values[i].first = value; - isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive(); - } - break; + for (size_t i = 0; i < relevantLength; i++) { + JSValue value = begin[i].get(); + ASSERT(!value.isUndefined()); + values[i].first = value; + isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive(); } // FIXME: The following loop continues to call toString on subsequent values even after @@ -1138,10 +910,8 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan // If the toString function changed the length of the array or vector storage, // increase the length to handle the orignal number of actual values. switch (indexingType) { - case ArrayWithInt32: - case ArrayWithDouble: case ArrayWithContiguous: - ensureLength(globalData, relevantLength); + ensureContiguousLength(globalData, relevantLength); break; case ArrayWithArrayStorage: @@ -1157,12 +927,8 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan CRASH(); } - for (size_t i = 0; i < relevantLength; i++) { - if (indexingType == ArrayWithDouble) - static_cast<double*>(begin)[i] = values[i].first.asNumber(); - else - static_cast<WriteBarrier<Unknown>*>(begin)[i].set(globalData, this, values[i].first); - } + for (size_t i = 0; i < relevantLength; i++) + begin[i].set(globalData, this, values[i].first); Heap::heap(this)->popTempSortVector(&values); } @@ -1173,31 +939,8 @@ void JSArray::sort(ExecState* exec) switch (structure()->indexingType()) { case ArrayClass: - case ArrayWithUndecided: return; - case ArrayWithInt32: { - unsigned lengthNotIncludingUndefined; - unsigned newRelevantLength; - compactForSorting<ArrayWithInt32>( - lengthNotIncludingUndefined, newRelevantLength); - - sortCompactedVector<ArrayWithInt32>( - exec, m_butterfly->contiguousInt32(), lengthNotIncludingUndefined); - return; - } - - case ArrayWithDouble: { - unsigned lengthNotIncludingUndefined; - unsigned newRelevantLength; - compactForSorting<ArrayWithDouble>( - lengthNotIncludingUndefined, newRelevantLength); - - sortCompactedVector<ArrayWithDouble>( - exec, m_butterfly->contiguousDouble(), lengthNotIncludingUndefined); - return; - } - case ArrayWithContiguous: { unsigned lengthNotIncludingUndefined; unsigned newRelevantLength; @@ -1344,12 +1087,12 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call unsigned numDefined = 0; unsigned numUndefined = 0; - + // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree. for (; numDefined < usedVectorLength; ++numDefined) { if (numDefined > m_butterfly->vectorLength()) break; - JSValue v = getHolyIndexQuickly(numDefined); + JSValue v = currentIndexingData()[numDefined].get(); if (!v || v.isUndefined()) break; tree.abstractor().m_nodes[numDefined].value = v; @@ -1358,7 +1101,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call for (unsigned i = numDefined; i < usedVectorLength; ++i) { if (i > m_butterfly->vectorLength()) break; - JSValue v = getHolyIndexQuickly(i); + JSValue v = currentIndexingData()[i].get(); if (v) { if (v.isUndefined()) ++numUndefined; @@ -1369,7 +1112,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call } } } - + unsigned newUsedVectorLength = numDefined + numUndefined; // The array size may have changed. Figure out the new bounds. @@ -1384,31 +1127,16 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call iter.start_iter_least(tree); JSGlobalData& globalData = exec->globalData(); for (unsigned i = 0; i < elementsToExtractThreshold; ++i) { - if (structure()->indexingType() == ArrayWithDouble) - butterfly()->contiguousDouble()[i] = tree.abstractor().m_nodes[*iter].value.asNumber(); - else - currentIndexingData()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value); + currentIndexingData()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value); ++iter; } // Put undefined values back in. - switch (structure()->indexingType()) { - case ArrayWithInt32: - case ArrayWithDouble: - ASSERT(elementsToExtractThreshold == undefinedElementsThreshold); - break; - - default: - for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i) - currentIndexingData()[i].setUndefined(); - } + for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i) + currentIndexingData()[i].setUndefined(); // Ensure that unused values in the vector are zeroed out. - for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i) { - if (structure()->indexingType() == ArrayWithDouble) - butterfly()->contiguousDouble()[i] = QNaN; - else - currentIndexingData()[i].clear(); - } + for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i) + currentIndexingData()[i].clear(); if (hasArrayStorage(structure()->indexingType())) arrayStorage()->m_numValuesInVector = newUsedVectorLength; @@ -1420,17 +1148,8 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, switch (structure()->indexingType()) { case ArrayClass: - case ArrayWithUndecided: return; - case ArrayWithInt32: - sortVector<ArrayWithInt32>(exec, compareFunction, callType, callData); - return; - - case ArrayWithDouble: - sortVector<ArrayWithDouble>(exec, compareFunction, callType, callData); - return; - case ArrayWithContiguous: sortVector<ArrayWithContiguous>(exec, compareFunction, callType, callData); return; @@ -1454,30 +1173,11 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) case ArrayClass: return; - case ArrayWithUndecided: { - vector = 0; - vectorEnd = 0; - break; - } - - case ArrayWithInt32: case ArrayWithContiguous: { vectorEnd = m_butterfly->publicLength(); vector = m_butterfly->contiguous(); break; } - - case ArrayWithDouble: { - vector = 0; - vectorEnd = 0; - for (; i < m_butterfly->publicLength(); ++i) { - double v = butterfly()->contiguousDouble()[i]; - if (v != v) - break; - args.append(JSValue(JSValue::EncodeAsDouble, v)); - } - break; - } case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); @@ -1516,31 +1216,12 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t le case ArrayClass: return; - case ArrayWithUndecided: { - vector = 0; - vectorEnd = 0; - break; - } - - case ArrayWithInt32: case ArrayWithContiguous: { vector = m_butterfly->contiguous(); vectorEnd = m_butterfly->publicLength(); break; } - case ArrayWithDouble: { - vector = 0; - vectorEnd = 0; - for (; i < m_butterfly->publicLength(); ++i) { - double v = m_butterfly->contiguousDouble()[i]; - if (v != v) - break; - callFrame->setArgument(i, JSValue(JSValue::EncodeAsDouble, v)); - } - break; - } - case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); vector = storage->m_vector; @@ -1578,40 +1259,12 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt unsigned numUndefined = 0; for (; numDefined < myRelevantLength; ++numDefined) { - if (indexingType == ArrayWithInt32) { - JSValue v = m_butterfly->contiguousInt32()[numDefined].get(); - if (!v) - break; - ASSERT(v.isInt32()); - continue; - } - if (indexingType == ArrayWithDouble) { - double v = m_butterfly->contiguousDouble()[numDefined]; - if (v != v) - break; - continue; - } JSValue v = indexingData<indexingType>()[numDefined].get(); if (!v || v.isUndefined()) break; } for (unsigned i = numDefined; i < myRelevantLength; ++i) { - if (indexingType == ArrayWithInt32) { - JSValue v = m_butterfly->contiguousInt32()[i].get(); - if (!v) - continue; - ASSERT(v.isInt32()); - m_butterfly->contiguousInt32()[numDefined++].setWithoutWriteBarrier(v); - continue; - } - if (indexingType == ArrayWithDouble) { - double v = m_butterfly->contiguousDouble()[i]; - if (v != v) - continue; - m_butterfly->contiguousDouble()[numDefined++] = v; - continue; - } JSValue v = indexingData<indexingType>()[i].get(); if (v) { if (v.isUndefined()) @@ -1626,23 +1279,10 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt if (hasArrayStorage(indexingType)) ASSERT(!arrayStorage()->m_sparseMap); - switch (indexingType) { - case ArrayWithInt32: - case ArrayWithDouble: - ASSERT(numDefined == newRelevantLength); - break; - - default: - for (unsigned i = numDefined; i < newRelevantLength; ++i) - indexingData<indexingType>()[i].setUndefined(); - break; - } - for (unsigned i = newRelevantLength; i < myRelevantLength; ++i) { - if (indexingType == ArrayWithDouble) - m_butterfly->contiguousDouble()[i] = QNaN; - else - indexingData<indexingType>()[i].clear(); - } + for (unsigned i = numDefined; i < newRelevantLength; ++i) + indexingData<indexingType>()[i].setUndefined(); + for (unsigned i = newRelevantLength; i < myRelevantLength; ++i) + indexingData<indexingType>()[i].clear(); if (hasArrayStorage(indexingType)) arrayStorage()->m_numValuesInVector = newRelevantLength; diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h index ea1ed9047..1d1e64173 100644 --- a/Source/JavaScriptCore/runtime/JSArray.h +++ b/Source/JavaScriptCore/runtime/JSArray.h @@ -22,7 +22,7 @@ #define JSArray_h #include "ArrayConventions.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" #include "JSObject.h" namespace JSC { @@ -162,7 +162,7 @@ private: void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&); template<IndexingType indexingType> - void sortCompactedVector(ExecState*, void* begin, unsigned relevantLength); + void sortCompactedVector(ExecState*, WriteBarrier<Unknown>* begin, unsigned relevantLength); template<IndexingType indexingType> void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&); @@ -174,14 +174,13 @@ private: void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength); }; -inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length, unsigned& vectorLength) +inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length) { IndexingHeader header; - vectorLength = std::max(length, BASE_VECTOR_LEN); - header.setVectorLength(vectorLength); + header.setVectorLength(std::max(length, BASE_VECTOR_LEN)); header.setPublicLength(length); Butterfly* result = Butterfly::create( - globalData, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue)); + globalData, 0, 0, true, header, header.vectorLength() * sizeof(EncodedJSValue)); return result; } @@ -201,23 +200,13 @@ Butterfly* createArrayButterflyInDictionaryIndexingMode(JSGlobalData&, unsigned inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength) { Butterfly* butterfly; - if (LIKELY(!hasArrayStorage(structure->indexingType()))) { - ASSERT( - hasUndecided(structure->indexingType()) - || hasInt32(structure->indexingType()) - || hasDouble(structure->indexingType()) - || hasContiguous(structure->indexingType())); - unsigned vectorLength; - butterfly = createContiguousArrayButterfly(globalData, initialLength, vectorLength); + if (LIKELY(structure->indexingType() == ArrayWithContiguous)) { + butterfly = createContiguousArrayButterfly(globalData, initialLength); ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX); - if (hasDouble(structure->indexingType())) { - for (unsigned i = 0; i < vectorLength; ++i) - butterfly->contiguousDouble()[i] = QNaN; - } } else { ASSERT( structure->indexingType() == ArrayWithSlowPutArrayStorage - || structure->indexingType() == ArrayWithArrayStorage); + || (initialLength && structure->indexingType() == ArrayWithArrayStorage)); butterfly = createArrayButterfly(globalData, initialLength); } JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly); @@ -232,13 +221,8 @@ inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Struct return 0; Butterfly* butterfly; - if (LIKELY(!hasArrayStorage(structure->indexingType()))) { - ASSERT( - hasUndecided(structure->indexingType()) - || hasInt32(structure->indexingType()) - || hasDouble(structure->indexingType()) - || hasContiguous(structure->indexingType())); - + if (LIKELY(structure->indexingType() == ArrayWithContiguous)) { + void* temp; if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp)) return 0; diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h index df31b8542..3b37613d1 100644 --- a/Source/JavaScriptCore/runtime/JSCell.h +++ b/Source/JavaScriptCore/runtime/JSCell.h @@ -28,9 +28,9 @@ #include "ConstructData.h" #include "Heap.h" #include "JSLock.h" -#include "JSValueInlines.h" +#include "JSValueInlineMethods.h" #include "SlotVisitor.h" -#include "SlotVisitorInlines.h" +#include "SlotVisitorInlineMethods.h" #include "TypedArrayDescriptor.h" #include "WriteBarrier.h" #include <wtf/Noncopyable.h> diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp index a7c6c8c18..c466a2b04 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -230,16 +230,9 @@ void JSGlobalObject::reset(JSValue prototype) m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get())); m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()))); - - m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithUndecided)); - m_originalArrayStructureForIndexingShape[Int32Shape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithInt32)); - m_originalArrayStructureForIndexingShape[DoubleShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithDouble)); - m_originalArrayStructureForIndexingShape[ContiguousShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous)); - m_originalArrayStructureForIndexingShape[ArrayStorageShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage)); - m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage)); - for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) - m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i]; - + m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous)); + m_arrayStructureWithArrayStorage.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage)); + m_arrayStructureForSlowPut.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage)); m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get())); m_stringPrototype.set(exec->globalData(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()))); @@ -367,9 +360,7 @@ inline bool hasBrokenIndexing(JSObject* object) { // This will change if we have more indexing types. IndexingType type = object->structure()->indexingType(); - // This could be made obviously more efficient, but isn't made so right now, because - // we expect this to be an unlikely slow path anyway. - return hasUndecided(type) || hasInt32(type) || hasDouble(type) || hasContiguous(type) || hasFastArrayStorage(type); + return hasContiguous(type) || hasFastArrayStorage(type); } void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell) @@ -421,8 +412,8 @@ void JSGlobalObject::haveABadTime(JSGlobalData& globalData) // Make sure that all JSArray allocations that load the appropriate structure from // this object now load a structure that uses SlowPut. - for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) - m_arrayStructureForIndexingShapeDuringAllocation[i].set(globalData, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage)); + m_arrayStructure.set(globalData, this, m_arrayStructureForSlowPut.get()); + m_arrayStructureWithArrayStorage.set(globalData, this, m_arrayStructureForSlowPut.get()); // Make sure that all objects that have indexed storage switch to the slow kind of // indexed storage. @@ -497,10 +488,9 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) visitor.append(&thisObject->m_activationStructure); visitor.append(&thisObject->m_nameScopeStructure); visitor.append(&thisObject->m_argumentsStructure); - for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) - visitor.append(&thisObject->m_originalArrayStructureForIndexingShape[i]); - for (unsigned i = 0; i < NumberOfIndexingShapes; ++i) - visitor.append(&thisObject->m_arrayStructureForIndexingShapeDuringAllocation[i]); + visitor.append(&thisObject->m_arrayStructure); + visitor.append(&thisObject->m_arrayStructureWithArrayStorage); + visitor.append(&thisObject->m_arrayStructureForSlowPut); visitor.append(&thisObject->m_booleanObjectStructure); visitor.append(&thisObject->m_callbackConstructorStructure); visitor.append(&thisObject->m_callbackFunctionStructure); diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h index 121b71b72..3212363ab 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h @@ -22,7 +22,6 @@ #ifndef JSGlobalObject_h #define JSGlobalObject_h -#include "ArrayAllocationProfile.h" #include "JSArray.h" #include "JSGlobalData.h" #include "JSSegmentedVariableObject.h" @@ -131,12 +130,9 @@ namespace JSC { WriteBarrier<Structure> m_activationStructure; WriteBarrier<Structure> m_nameScopeStructure; WriteBarrier<Structure> m_argumentsStructure; - - // Lists the actual structures used for having these particular indexing shapes. - WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; - // Lists the structures we should use during allocation for these particular indexing shapes. - WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; - + WriteBarrier<Structure> m_arrayStructure; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time. + WriteBarrier<Structure> m_arrayStructureWithArrayStorage; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time. + WriteBarrier<Structure> m_arrayStructureForSlowPut; WriteBarrier<Structure> m_booleanObjectStructure; WriteBarrier<Structure> m_callbackConstructorStructure; WriteBarrier<Structure> m_callbackFunctionStructure; @@ -279,26 +275,14 @@ namespace JSC { Structure* activationStructure() const { return m_activationStructure.get(); } Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } Structure* argumentsStructure() const { return m_argumentsStructure.get(); } - Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const - { - ASSERT(indexingType & IsArray); - return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); - } - Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const - { - ASSERT(indexingType & IsArray); - return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); - } - Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const - { - return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); - } - + Structure* arrayStructure() const { return m_arrayStructure.get(); } + Structure* arrayStructureWithArrayStorage() const { return m_arrayStructureWithArrayStorage.get(); } + void* addressOfArrayStructure() { return &m_arrayStructure; } + void* addressOfArrayStructureWithArrayStorage() { return &m_arrayStructureWithArrayStorage; } bool isOriginalArrayStructure(Structure* structure) { - return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; + return structure == m_arrayStructure.get() || structure == m_arrayStructureWithArrayStorage.get(); } - Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } @@ -513,34 +497,34 @@ namespace JSC { return constructEmptyObject(exec, exec->lexicalGlobalObject()); } - inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) + inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength = 0) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); + return JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureWithArrayStorage() : globalObject->arrayStructure(), initialLength); } - inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) + inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength = 0) { - return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); + return constructEmptyArray(exec, exec->lexicalGlobalObject(), initialLength); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) + inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const ArgList& values) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); + return constructArray(exec, globalObject->arrayStructure(), values); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) + inline JSArray* constructArray(ExecState* exec, const ArgList& values) { - return constructArray(exec, profile, exec->lexicalGlobalObject(), values); + return constructArray(exec, exec->lexicalGlobalObject(), values); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) + inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const JSValue* values, unsigned length) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); + return constructArray(exec, globalObject->arrayStructure(), values, length); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) + inline JSArray* constructArray(ExecState* exec, const JSValue* values, unsigned length) { - return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); + return constructArray(exec, exec->lexicalGlobalObject(), values, length); } class DynamicGlobalObjectScope { diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp index a67896b1a..6a3fb84e4 100644 --- a/Source/JavaScriptCore/runtime/JSObject.cpp +++ b/Source/JavaScriptCore/runtime/JSObject.cpp @@ -24,14 +24,14 @@ #include "config.h" #include "JSObject.h" -#include "ButterflyInlines.h" -#include "CopiedSpaceInlines.h" +#include "ButterflyInlineMethods.h" +#include "CopiedSpaceInlineMethods.h" #include "CopyVisitor.h" -#include "CopyVisitorInlines.h" +#include "CopyVisitorInlineMethods.h" #include "DatePrototype.h" #include "ErrorConstructor.h" #include "GetterSetter.h" -#include "IndexingHeaderInlines.h" +#include "IndexingHeaderInlineMethods.h" #include "JSFunction.h" #include "JSGlobalObject.h" #include "Lookup.h" @@ -42,7 +42,7 @@ #include "PropertyDescriptor.h" #include "PropertyNameArray.h" #include "Reject.h" -#include "SlotVisitorInlines.h" +#include "SlotVisitorInlineMethods.h" #include <math.h> #include <wtf/Assertions.h> @@ -129,16 +129,7 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt size_t count; switch (structure->indexingType()) { - case ALL_UNDECIDED_INDEXING_TYPES: { - currentTarget = 0; - currentSource = 0; - count = 0; - break; - } - - case ALL_CONTIGUOUS_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: { + case ALL_CONTIGUOUS_INDEXING_TYPES: { currentTarget = newButterfly->contiguous(); currentSource = butterfly->contiguous(); ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength()); @@ -161,7 +152,8 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt break; } - memcpy(currentTarget, currentSource, count * sizeof(EncodedJSValue)); + while (count--) + (currentTarget++)->setWithoutWriteBarrier((currentSource++)->get()); } m_butterfly = newButterfly; @@ -280,10 +272,8 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned switch (thisObject->structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: break; - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: { Butterfly* butterfly = thisObject->m_butterfly; if (i >= butterfly->vectorLength()) @@ -298,20 +288,6 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned return false; } - case ALL_DOUBLE_INDEXING_TYPES: { - Butterfly* butterfly = thisObject->m_butterfly; - if (i >= butterfly->vectorLength()) - return false; - - double value = butterfly->contiguousDouble()[i]; - if (value == value) { - slot.setValue(JSValue(JSValue::EncodeAsDouble, value)); - return true; - } - - return false; - } - case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = thisObject->m_butterfly->arrayStorage(); if (i >= storage->length()) @@ -429,22 +405,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, case ALL_BLANK_INDEXING_TYPES: break; - case ALL_UNDECIDED_INDEXING_TYPES: { - thisObject->convertUndecidedForValue(exec->globalData(), value); - // Reloop. - putByIndex(cell, exec, propertyName, value, shouldThrow); - return; - } - - case ALL_INT32_INDEXING_TYPES: { - if (!value.isInt32()) { - thisObject->convertInt32ForValue(exec->globalData(), value); - putByIndex(cell, exec, propertyName, value, shouldThrow); - return; - } - // Fall through. - } - case ALL_CONTIGUOUS_INDEXING_TYPES: { Butterfly* butterfly = thisObject->m_butterfly; if (propertyName >= butterfly->vectorLength()) @@ -455,29 +415,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, return; } - case ALL_DOUBLE_INDEXING_TYPES: { - if (!value.isNumber()) { - thisObject->convertDoubleToContiguous(exec->globalData()); - // Reloop. - putByIndex(cell, exec, propertyName, value, shouldThrow); - return; - } - double valueAsDouble = value.asNumber(); - if (valueAsDouble != valueAsDouble) { - thisObject->convertDoubleToContiguous(exec->globalData()); - // Reloop. - putByIndex(cell, exec, propertyName, value, shouldThrow); - return; - } - Butterfly* butterfly = thisObject->m_butterfly; - if (propertyName >= butterfly->vectorLength()) - break; - butterfly->contiguousDouble()[propertyName] = valueAsDouble; - if (propertyName >= butterfly->publicLength()) - butterfly->setPublicLength(propertyName + 1); - return; - } - case NonArrayWithArrayStorage: case ArrayWithArrayStorage: { ArrayStorage* storage = thisObject->m_butterfly->arrayStorage(); @@ -570,13 +507,10 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData) { switch (structure()->indexingType()) { - case ALL_UNDECIDED_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: // NOTE: this is horribly inefficient, as it will perform two conversions. We could optimize // this case if we ever cared. - enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, ensureArrayStorageSlow(globalData)); + enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData)); break; case ALL_ARRAY_STORAGE_INDEXING_TYPES: enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage()); @@ -600,7 +534,7 @@ void JSObject::notifyPresenceOfIndexedAccessors(JSGlobalData& globalData) globalObject()->haveABadTime(globalData); } -Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsigned length, size_t elementSize) +WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length) { ASSERT(length < MAX_ARRAY_INDEX); IndexingType oldType = structure()->indexingType(); @@ -610,41 +544,9 @@ Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsig unsigned vectorLength = std::max(length, BASE_VECTOR_LEN); Butterfly* newButterfly = m_butterfly->growArrayRight( globalData, structure(), structure()->outOfLineCapacity(), false, 0, - elementSize * vectorLength); + sizeof(EncodedJSValue) * vectorLength); newButterfly->setPublicLength(length); newButterfly->setVectorLength(vectorLength); - return newButterfly; -} - -Butterfly* JSObject::createInitialUndecided(JSGlobalData& globalData, unsigned length) -{ - Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue)); - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateUndecided); - setButterfly(globalData, newButterfly, newStructure); - return newButterfly; -} - -WriteBarrier<Unknown>* JSObject::createInitialInt32(JSGlobalData& globalData, unsigned length) -{ - Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue)); - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateInt32); - setButterfly(globalData, newButterfly, newStructure); - return newButterfly->contiguousInt32(); -} - -double* JSObject::createInitialDouble(JSGlobalData& globalData, unsigned length) -{ - Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(double)); - for (unsigned i = newButterfly->vectorLength(); i--;) - newButterfly->contiguousDouble()[i] = QNaN; - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateDouble); - setButterfly(globalData, newButterfly, newStructure); - return newButterfly->contiguousDouble(); -} - -WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length) -{ - Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue)); Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous); setButterfly(globalData, newButterfly, newStructure); return newButterfly->contiguous(); @@ -675,33 +577,10 @@ ArrayStorage* JSObject::createInitialArrayStorage(JSGlobalData& globalData) return createArrayStorage(globalData, 0, BASE_VECTOR_LEN); } -WriteBarrier<Unknown>* JSObject::convertUndecidedToInt32(JSGlobalData& globalData) -{ - ASSERT(hasUndecided(structure()->indexingType())); - setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateInt32)); - return m_butterfly->contiguousInt32(); -} - -double* JSObject::convertUndecidedToDouble(JSGlobalData& globalData) +ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength) { - ASSERT(hasUndecided(structure()->indexingType())); - - for (unsigned i = m_butterfly->vectorLength(); i--;) - m_butterfly->contiguousDouble()[i] = QNaN; + ASSERT(hasContiguous(structure()->indexingType())); - setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateDouble)); - return m_butterfly->contiguousDouble(); -} - -WriteBarrier<Unknown>* JSObject::convertUndecidedToContiguous(JSGlobalData& globalData) -{ - ASSERT(hasUndecided(structure()->indexingType())); - setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous)); - return m_butterfly->contiguous(); -} - -ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(JSGlobalData& globalData, unsigned neededLength) -{ unsigned publicLength = m_butterfly->publicLength(); unsigned propertyCapacity = structure()->outOfLineCapacity(); unsigned propertySize = structure()->outOfLineSize(); @@ -720,141 +599,7 @@ ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(JSG newStorage->m_sparseMap.clear(); newStorage->m_indexBias = 0; newStorage->m_numValuesInVector = 0; - - return newStorage; -} - -ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength) -{ - ASSERT(hasUndecided(structure()->indexingType())); - - ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength); - // No need to copy elements. - - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition); - setButterfly(globalData, storage->butterfly(), newStructure); - return storage; -} - -ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition) -{ - return convertUndecidedToArrayStorage(globalData, transition, m_butterfly->vectorLength()); -} - -ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData) -{ - return convertUndecidedToArrayStorage(globalData, structure()->suggestedArrayStorageTransition()); -} - -double* JSObject::convertInt32ToDouble(JSGlobalData& globalData) -{ - ASSERT(hasInt32(structure()->indexingType())); - - for (unsigned i = m_butterfly->vectorLength(); i--;) { - WriteBarrier<Unknown>* current = &m_butterfly->contiguousInt32()[i]; - double* currentAsDouble = bitwise_cast<double*>(current); - JSValue v = current->get(); - if (!v) { - *currentAsDouble = QNaN; - continue; - } - ASSERT(v.isInt32()); - *currentAsDouble = v.asInt32(); - } - - setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateDouble)); - return m_butterfly->contiguousDouble(); -} - -WriteBarrier<Unknown>* JSObject::convertInt32ToContiguous(JSGlobalData& globalData) -{ - ASSERT(hasInt32(structure()->indexingType())); - - setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous)); - return m_butterfly->contiguous(); -} - -ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength) -{ - ASSERT(hasInt32(structure()->indexingType())); - - ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength); - for (unsigned i = m_butterfly->publicLength(); i--;) { - JSValue v = m_butterfly->contiguous()[i].get(); - if (!v) - continue; - newStorage->m_vector[i].setWithoutWriteBarrier(v); - newStorage->m_numValuesInVector++; - } - - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition); - setButterfly(globalData, newStorage->butterfly(), newStructure); - return newStorage; -} - -ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition) -{ - return convertInt32ToArrayStorage(globalData, transition, m_butterfly->vectorLength()); -} - -ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData) -{ - return convertInt32ToArrayStorage(globalData, structure()->suggestedArrayStorageTransition()); -} - -WriteBarrier<Unknown>* JSObject::convertDoubleToContiguous(JSGlobalData& globalData) -{ - ASSERT(hasDouble(structure()->indexingType())); - - for (unsigned i = m_butterfly->vectorLength(); i--;) { - double* current = &m_butterfly->contiguousDouble()[i]; - WriteBarrier<Unknown>* currentAsValue = bitwise_cast<WriteBarrier<Unknown>*>(current); - double value = *current; - if (value != value) { - currentAsValue->clear(); - continue; - } - currentAsValue->setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value)); - } - - setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous)); - return m_butterfly->contiguous(); -} - -ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength) -{ - ASSERT(hasDouble(structure()->indexingType())); - - ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength); - for (unsigned i = m_butterfly->publicLength(); i--;) { - double value = m_butterfly->contiguousDouble()[i]; - if (value != value) - continue; - newStorage->m_vector[i].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value)); - newStorage->m_numValuesInVector++; - } - - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition); - setButterfly(globalData, newStorage->butterfly(), newStructure); - return newStorage; -} - -ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition) -{ - return convertDoubleToArrayStorage(globalData, transition, m_butterfly->vectorLength()); -} - -ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData) -{ - return convertDoubleToArrayStorage(globalData, structure()->suggestedArrayStorageTransition()); -} - -ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength) -{ - ASSERT(hasContiguous(structure()->indexingType())); - - ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength); - for (unsigned i = m_butterfly->publicLength(); i--;) { + for (unsigned i = publicLength; i--;) { JSValue v = m_butterfly->contiguous()[i].get(); if (!v) continue; @@ -863,7 +608,7 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData } Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition); - setButterfly(globalData, newStorage->butterfly(), newStructure); + setButterfly(globalData, newButterfly, newStructure); return newStorage; } @@ -877,154 +622,48 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData return convertContiguousToArrayStorage(globalData, structure()->suggestedArrayStorageTransition()); } -void JSObject::convertUndecidedForValue(JSGlobalData& globalData, JSValue value) -{ - if (value.isInt32()) { - convertUndecidedToInt32(globalData); - return; - } - - if (value.isDouble()) { - convertUndecidedToDouble(globalData); - return; - } - - convertUndecidedToContiguous(globalData); -} - -void JSObject::convertInt32ForValue(JSGlobalData& globalData, JSValue value) -{ - ASSERT(!value.isInt32()); - - if (value.isDouble()) { - convertInt32ToDouble(globalData); - return; - } - - convertInt32ToContiguous(globalData); -} - -void JSObject::setIndexQuicklyToUndecided(JSGlobalData& globalData, unsigned index, JSValue value) -{ - ASSERT(index < m_butterfly->publicLength()); - ASSERT(index < m_butterfly->vectorLength()); - convertUndecidedForValue(globalData, value); - setIndexQuickly(globalData, index, value); -} - -void JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(JSGlobalData& globalData, unsigned index, JSValue value) -{ - ASSERT(!value.isInt32()); - convertInt32ForValue(globalData, value); - setIndexQuickly(globalData, index, value); -} - -void JSObject::convertDoubleToContiguousWhilePerformingSetIndex(JSGlobalData& globalData, unsigned index, JSValue value) -{ - ASSERT(!value.isNumber() || value.asNumber() != value.asNumber()); - convertDoubleToContiguous(globalData); - setIndexQuickly(globalData, index, value); -} - -WriteBarrier<Unknown>* JSObject::ensureInt32Slow(JSGlobalData& globalData) +WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData) { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing())) return 0; - return createInitialInt32(globalData, 0); - - case ALL_UNDECIDED_INDEXING_TYPES: - return convertUndecidedToInt32(globalData); - - case ALL_DOUBLE_INDEXING_TYPES: - case ALL_CONTIGUOUS_INDEXING_TYPES: - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return 0; + return createInitialContiguous(globalData, 0); default: - CRASH(); + ASSERT_NOT_REACHED(); return 0; } } -double* JSObject::ensureDoubleSlow(JSGlobalData& globalData) +ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData) { switch (structure()->indexingType()) { - case ALL_BLANK_INDEXING_TYPES: - if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing())) - return 0; - return createInitialDouble(globalData, 0); - - case ALL_UNDECIDED_INDEXING_TYPES: - return convertUndecidedToDouble(globalData); - - case ALL_INT32_INDEXING_TYPES: - return convertInt32ToDouble(globalData); - case ALL_CONTIGUOUS_INDEXING_TYPES: - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return 0; + ASSERT(!indexingShouldBeSparse()); + ASSERT(!structure()->needsSlowPutIndexing()); + return convertContiguousToArrayStorage(globalData); - default: - CRASH(); - return 0; - } -} - -WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData) -{ - switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing())) - return 0; - return createInitialContiguous(globalData, 0); - - case ALL_UNDECIDED_INDEXING_TYPES: - return convertUndecidedToContiguous(globalData); - - case ALL_INT32_INDEXING_TYPES: - return convertInt32ToContiguous(globalData); - - case ALL_DOUBLE_INDEXING_TYPES: - return convertDoubleToContiguous(globalData); - - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return 0; + if (UNLIKELY(indexingShouldBeSparse())) + return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData); + return createInitialArrayStorage(globalData); default: - CRASH(); + ASSERT_NOT_REACHED(); return 0; } } -ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData) +Butterfly* JSObject::ensureIndexedStorageSlow(JSGlobalData& globalData) { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: + if (UNLIKELY(structure()->needsSlowPutIndexing())) + return createInitialArrayStorage(globalData)->butterfly(); if (UNLIKELY(indexingShouldBeSparse())) - return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData); - return createInitialArrayStorage(globalData); - - case ALL_UNDECIDED_INDEXING_TYPES: - ASSERT(!indexingShouldBeSparse()); - ASSERT(!structure()->needsSlowPutIndexing()); - return convertUndecidedToArrayStorage(globalData); - - case ALL_INT32_INDEXING_TYPES: - ASSERT(!indexingShouldBeSparse()); - ASSERT(!structure()->needsSlowPutIndexing()); - return convertInt32ToArrayStorage(globalData); - - case ALL_DOUBLE_INDEXING_TYPES: - ASSERT(!indexingShouldBeSparse()); - ASSERT(!structure()->needsSlowPutIndexing()); - return convertDoubleToArrayStorage(globalData); - - case ALL_CONTIGUOUS_INDEXING_TYPES: - ASSERT(!indexingShouldBeSparse()); - ASSERT(!structure()->needsSlowPutIndexing()); - return convertContiguousToArrayStorage(globalData); + return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)->butterfly(); + return Butterfly::fromContiguous(createInitialContiguous(globalData, 0)); default: ASSERT_NOT_REACHED(); @@ -1035,6 +674,13 @@ ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData) ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData& globalData) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + // FIXME: This could be made way more efficient, if we cared. + return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData)); + + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage()); + case ALL_BLANK_INDEXING_TYPES: { createArrayStorage(globalData, 0, 0); SparseArrayValueMap* map = allocateSparseIndexMap(globalData); @@ -1042,23 +688,8 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J return arrayStorage(); } - case ALL_UNDECIDED_INDEXING_TYPES: - return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertUndecidedToArrayStorage(globalData)); - - case ALL_INT32_INDEXING_TYPES: - return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertInt32ToArrayStorage(globalData)); - - case ALL_DOUBLE_INDEXING_TYPES: - return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertDoubleToArrayStorage(globalData)); - - case ALL_CONTIGUOUS_INDEXING_TYPES: - return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData)); - - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage()); - default: - CRASH(); + ASSERT_NOT_REACHED(); return 0; } } @@ -1066,21 +697,10 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData) { switch (structure()->indexingType()) { - case ALL_UNDECIDED_INDEXING_TYPES: - convertUndecidedToArrayStorage(globalData, AllocateSlowPutArrayStorage); - break; - - case ALL_INT32_INDEXING_TYPES: - convertInt32ToArrayStorage(globalData, AllocateSlowPutArrayStorage); - break; - - case ALL_DOUBLE_INDEXING_TYPES: - convertDoubleToArrayStorage(globalData, AllocateSlowPutArrayStorage); - break; - - case ALL_CONTIGUOUS_INDEXING_TYPES: + case ALL_CONTIGUOUS_INDEXING_TYPES: { convertContiguousToArrayStorage(globalData, AllocateSlowPutArrayStorage); break; + } case NonArrayWithArrayStorage: case ArrayWithArrayStorage: { @@ -1090,7 +710,7 @@ void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData) } default: - CRASH(); + ASSERT_NOT_REACHED(); break; } } @@ -1257,10 +877,8 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) switch (thisObject->structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: return true; - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: { Butterfly* butterfly = thisObject->m_butterfly; if (i >= butterfly->vectorLength()) @@ -1269,14 +887,6 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) return true; } - case ALL_DOUBLE_INDEXING_TYPES: { - Butterfly* butterfly = thisObject->m_butterfly; - if (i >= butterfly->vectorLength()) - return true; - butterfly->contiguousDouble()[i] = QNaN; - return true; - } - case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = thisObject->m_butterfly->arrayStorage(); @@ -1448,10 +1058,8 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa // which almost certainly means a different structure for PropertyNameArray. switch (object->structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: break; - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: { Butterfly* butterfly = object->m_butterfly; unsigned usedLength = butterfly->publicLength(); @@ -1463,18 +1071,6 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa break; } - case ALL_DOUBLE_INDEXING_TYPES: { - Butterfly* butterfly = object->m_butterfly; - unsigned usedLength = butterfly->publicLength(); - for (unsigned i = 0; i < usedLength; ++i) { - double value = butterfly->contiguousDouble()[i]; - if (value != value) - continue; - propertyNames.add(Identifier::from(exec, i)); - } - break; - } - case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = object->m_butterfly->arrayStorage(); @@ -1864,10 +1460,9 @@ bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, J return asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow); } -template<IndexingType indexingShape> -void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, unsigned i, JSValue value) +void JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState* exec, unsigned i, JSValue value) { - ASSERT((structure()->indexingType() & IndexingShapeMask) == indexingShape); + ASSERT(hasContiguous(structure()->indexingType())); ASSERT(!indexingShouldBeSparse()); // For us to get here, the index is either greater than the public length, or greater than @@ -1878,9 +1473,9 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un if (i >= MAX_ARRAY_INDEX - 1 || (i >= MIN_SPARSE_ARRAY_INDEX - && !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly)))) { + && !isDenseEnoughForVector(i, countElementsInContiguous(m_butterfly)))) { ASSERT(i <= MAX_ARRAY_INDEX); - ensureArrayStorageSlow(globalData); + convertContiguousToArrayStorage(globalData, AllocateArrayStorage); SparseArrayValueMap* map = allocateSparseIndexMap(globalData); map->putEntry(exec, this, i, value, false); ASSERT(i >= arrayStorage()->length()); @@ -1888,30 +1483,10 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un return; } - ensureLength(globalData, i + 1); + ensureContiguousLength(globalData, i + 1); ASSERT(i < m_butterfly->vectorLength()); - switch (indexingShape) { - case Int32Shape: - ASSERT(value.isInt32()); - m_butterfly->contiguousInt32()[i].setWithoutWriteBarrier(value); - break; - - case DoubleShape: { - ASSERT(value.isNumber()); - double valueAsDouble = value.asNumber(); - ASSERT(valueAsDouble == valueAsDouble); - m_butterfly->contiguousDouble()[i] = valueAsDouble; - break; - } - - case ContiguousShape: - m_butterfly->contiguous()[i].set(globalData, this, value); - break; - - default: - CRASH(); - } + m_butterfly->contiguous()[i].set(globalData, this, value); } void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, ArrayStorage* storage) @@ -2017,23 +1592,8 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue break; } - case ALL_UNDECIDED_INDEXING_TYPES: { - CRASH(); - break; - } - - case ALL_INT32_INDEXING_TYPES: { - putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, i, value); - break; - } - - case ALL_DOUBLE_INDEXING_TYPES: { - putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, i, value); - break; - } - case ALL_CONTIGUOUS_INDEXING_TYPES: { - putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, i, value); + putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value); break; } @@ -2164,49 +1724,12 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV return true; } - case ALL_UNDECIDED_INDEXING_TYPES: { - convertUndecidedForValue(exec->globalData(), value); - // Reloop. - return putDirectIndex(exec, i, value, attributes, mode); - } - - case ALL_INT32_INDEXING_TYPES: { - if (attributes & (ReadOnly | Accessor)) { - return putDirectIndexBeyondVectorLengthWithArrayStorage( - exec, i, value, attributes, mode, convertInt32ToArrayStorage(globalData)); - } - if (!value.isInt32()) { - convertInt32ForValue(globalData, value); - return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode); - } - putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, i, value); - return true; - } - - case ALL_DOUBLE_INDEXING_TYPES: { - if (attributes & (ReadOnly | Accessor)) { - return putDirectIndexBeyondVectorLengthWithArrayStorage( - exec, i, value, attributes, mode, convertDoubleToArrayStorage(globalData)); - } - if (!value.isNumber()) { - convertDoubleToContiguous(globalData); - return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode); - } - double valueAsDouble = value.asNumber(); - if (valueAsDouble != valueAsDouble) { - convertDoubleToContiguous(globalData); - return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode); - } - putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, i, value); - return true; - } - case ALL_CONTIGUOUS_INDEXING_TYPES: { if (attributes & (ReadOnly | Accessor)) { return putDirectIndexBeyondVectorLengthWithArrayStorage( exec, i, value, attributes, mode, convertContiguousToArrayStorage(globalData)); } - putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, i, value); + putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value); return true; } @@ -2246,65 +1769,33 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength) unsigned vectorLength; unsigned length; - if (hasIndexedProperties(structure()->indexingType())) { - vectorLength = m_butterfly->vectorLength(); - length = m_butterfly->publicLength(); - } else { + switch (structure()->indexingType()) { + case ALL_BLANK_INDEXING_TYPES: vectorLength = 0; length = 0; + break; + case ALL_CONTIGUOUS_INDEXING_TYPES: + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + vectorLength = m_butterfly->vectorLength(); + length = m_butterfly->publicLength(); + break; + default: + CRASH(); + return 0; } - return getNewVectorLength(vectorLength, length, desiredLength); } -template<IndexingType indexingShape> -unsigned JSObject::countElements(Butterfly* butterfly) +unsigned JSObject::countElementsInContiguous(Butterfly* butterfly) { unsigned numValues = 0; for (unsigned i = butterfly->publicLength(); i--;) { - switch (indexingShape) { - case Int32Shape: - case ContiguousShape: - if (butterfly->contiguous()[i]) - numValues++; - break; - - case DoubleShape: { - double value = butterfly->contiguousDouble()[i]; - if (value == value) - numValues++; - break; - } - - default: - CRASH(); - } + if (butterfly->contiguous()[i]) + numValues++; } return numValues; } -unsigned JSObject::countElements() -{ - switch (structure()->indexingType()) { - case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - return 0; - - case ALL_INT32_INDEXING_TYPES: - return countElements<Int32Shape>(m_butterfly); - - case ALL_DOUBLE_INDEXING_TYPES: - return countElements<DoubleShape>(m_butterfly); - - case ALL_CONTIGUOUS_INDEXING_TYPES: - return countElements<ContiguousShape>(m_butterfly); - - default: - CRASH(); - return 0; - } -} - bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength) { // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map @@ -2348,24 +1839,19 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength return true; } -void JSObject::ensureLengthSlow(JSGlobalData& globalData, unsigned length) +void JSObject::ensureContiguousLengthSlow(JSGlobalData& globalData, unsigned length) { ASSERT(length < MAX_ARRAY_INDEX); - ASSERT(hasContiguous(structure()->indexingType()) || hasInt32(structure()->indexingType()) || hasDouble(structure()->indexingType()) || hasUndecided(structure()->indexingType())); + ASSERT(hasContiguous(structure()->indexingType())); ASSERT(length > m_butterfly->vectorLength()); unsigned newVectorLength = std::min( length << 1, MAX_STORAGE_VECTOR_LENGTH); - unsigned oldVectorLength = m_butterfly->vectorLength(); m_butterfly = m_butterfly->growArrayRight( globalData, structure(), structure()->outOfLineCapacity(), true, - oldVectorLength * sizeof(EncodedJSValue), + m_butterfly->vectorLength() * sizeof(EncodedJSValue), newVectorLength * sizeof(EncodedJSValue)); - if (hasDouble(structure()->indexingType())) { - for (unsigned i = oldVectorLength; i < newVectorLength; ++i) - m_butterfly->contiguousDouble()[i] = QNaN; - } m_butterfly->setVectorLength(newVectorLength); } @@ -2395,10 +1881,8 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope switch (object->structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: return false; - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: { Butterfly* butterfly = object->m_butterfly; if (i >= butterfly->vectorLength()) @@ -2410,17 +1894,6 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope return true; } - case ALL_DOUBLE_INDEXING_TYPES: { - Butterfly* butterfly = object->m_butterfly; - if (i >= butterfly->vectorLength()) - return false; - double value = butterfly->contiguousDouble()[i]; - if (value != value) - return false; - descriptor.setDescriptor(JSValue(JSValue::EncodeAsDouble, value), 0); - return true; - } - case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = object->m_butterfly->arrayStorage(); if (i >= storage->length()) diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h index f9ae73ed4..82455390f 100644 --- a/Source/JavaScriptCore/runtime/JSObject.h +++ b/Source/JavaScriptCore/runtime/JSObject.h @@ -151,16 +151,30 @@ public: unsigned getArrayLength() const { - if (!hasIndexedProperties(structure()->indexingType())) + switch (structure()->indexingType()) { + case ALL_BLANK_INDEXING_TYPES: return 0; - return m_butterfly->publicLength(); + case ALL_CONTIGUOUS_INDEXING_TYPES: + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return m_butterfly->publicLength(); + default: + ASSERT_NOT_REACHED(); + return 0; + } } unsigned getVectorLength() { - if (!hasIndexedProperties(structure()->indexingType())) + switch (structure()->indexingType()) { + case ALL_BLANK_INDEXING_TYPES: return 0; - return m_butterfly->vectorLength(); + case ALL_CONTIGUOUS_INDEXING_TYPES: + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return m_butterfly->vectorLength(); + default: + ASSERT_NOT_REACHED(); + return 0; + } } JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); @@ -200,19 +214,9 @@ public: { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: return false; - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return i < m_butterfly->vectorLength() && m_butterfly->contiguous()[i]; - case ALL_DOUBLE_INDEXING_TYPES: { - if (i >= m_butterfly->vectorLength()) - return false; - double value = m_butterfly->contiguousDouble()[i]; - if (value != value) - return false; - return true; - } case ALL_ARRAY_STORAGE_INDEXING_TYPES: return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i]; default: @@ -224,11 +228,8 @@ public: JSValue getIndexQuickly(unsigned i) { switch (structure()->indexingType()) { - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return m_butterfly->contiguous()[i].get(); - case ALL_DOUBLE_INDEXING_TYPES: - return JSValue(JSValue::EncodeAsDouble, m_butterfly->contiguousDouble()[i]); case ALL_ARRAY_STORAGE_INDEXING_TYPES: return m_butterfly->arrayStorage()->m_vector[i].get(); default: @@ -242,19 +243,10 @@ public: switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: break; - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: if (i < m_butterfly->publicLength()) return m_butterfly->contiguous()[i].get(); break; - case ALL_DOUBLE_INDEXING_TYPES: { - if (i >= m_butterfly->publicLength()) - break; - double result = m_butterfly->contiguousDouble()[i]; - if (result != result) - break; - return JSValue(JSValue::EncodeAsDouble, result); - } case ALL_ARRAY_STORAGE_INDEXING_TYPES: if (i < m_butterfly->arrayStorage()->vectorLength()) return m_butterfly->arrayStorage()->m_vector[i].get(); @@ -287,10 +279,7 @@ public: { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: return false; - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: case NonArrayWithArrayStorage: case ArrayWithArrayStorage: @@ -309,10 +298,7 @@ public: { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: return false; - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: case ALL_ARRAY_STORAGE_INDEXING_TYPES: return i < m_butterfly->vectorLength(); @@ -325,14 +311,6 @@ public: void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v) { switch (structure()->indexingType()) { - case ALL_INT32_INDEXING_TYPES: { - ASSERT(i < m_butterfly->vectorLength()); - if (!v.isInt32()) { - convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(globalData, i, v); - return; - } - // Fall through to contiguous case. - } case ALL_CONTIGUOUS_INDEXING_TYPES: { ASSERT(i < m_butterfly->vectorLength()); m_butterfly->contiguous()[i].set(globalData, this, v); @@ -340,22 +318,6 @@ public: m_butterfly->setPublicLength(i + 1); break; } - case ALL_DOUBLE_INDEXING_TYPES: { - ASSERT(i < m_butterfly->vectorLength()); - if (!v.isNumber()) { - convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v); - return; - } - double value = v.asNumber(); - if (value != value) { - convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v); - return; - } - m_butterfly->contiguousDouble()[i] = value; - if (i >= m_butterfly->publicLength()) - m_butterfly->setPublicLength(i + 1); - break; - } case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); WriteBarrier<Unknown>& x = storage->m_vector[i]; @@ -376,40 +338,12 @@ public: void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v) { switch (structure()->indexingType()) { - case ALL_UNDECIDED_INDEXING_TYPES: { - setIndexQuicklyToUndecided(globalData, i, v); - break; - } - case ALL_INT32_INDEXING_TYPES: { - ASSERT(i < m_butterfly->publicLength()); - ASSERT(i < m_butterfly->vectorLength()); - if (!v.isInt32()) { - convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(globalData, i, v); - break; - } - // Fall through. - } case ALL_CONTIGUOUS_INDEXING_TYPES: { ASSERT(i < m_butterfly->publicLength()); ASSERT(i < m_butterfly->vectorLength()); m_butterfly->contiguous()[i].set(globalData, this, v); break; } - case ALL_DOUBLE_INDEXING_TYPES: { - ASSERT(i < m_butterfly->publicLength()); - ASSERT(i < m_butterfly->vectorLength()); - if (!v.isNumber()) { - convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v); - return; - } - double value = v.asNumber(); - if (value != value) { - convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v); - return; - } - m_butterfly->contiguousDouble()[i] = value; - break; - } case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); ASSERT(i < storage->length()); @@ -426,9 +360,6 @@ public: { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return false; case ALL_ARRAY_STORAGE_INDEXING_TYPES: @@ -443,9 +374,6 @@ public: { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: - case ALL_UNDECIDED_INDEXING_TYPES: - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return false; case ALL_ARRAY_STORAGE_INDEXING_TYPES: @@ -643,30 +571,6 @@ public: // foo->attemptToInterceptPutByIndexOnHole(...); bool attemptToInterceptPutByIndexOnHoleForPrototype(ExecState*, JSValue thisValue, unsigned propertyName, JSValue, bool shouldThrow); - // Returns 0 if int32 storage cannot be created - either because - // indexing should be sparse, we're having a bad time, or because - // we already have a more general form of storage (double, - // contiguous, array storage). - WriteBarrier<Unknown>* ensureInt32(JSGlobalData& globalData) - { - if (LIKELY(hasInt32(structure()->indexingType()))) - return m_butterfly->contiguousInt32(); - - return ensureInt32Slow(globalData); - } - - // Returns 0 if double storage cannot be created - either because - // indexing should be sparse, we're having a bad time, or because - // we already have a more general form of storage (contiguous, - // or array storage). - double* ensureDouble(JSGlobalData& globalData) - { - if (LIKELY(hasDouble(structure()->indexingType()))) - return m_butterfly->contiguousDouble(); - - return ensureDoubleSlow(globalData); - } - // Returns 0 if contiguous storage cannot be created - either because // indexing should be sparse or because we're having a bad time. WriteBarrier<Unknown>* ensureContiguous(JSGlobalData& globalData) @@ -689,6 +593,14 @@ public: return ensureArrayStorageSlow(globalData); } + Butterfly* ensureIndexedStorage(JSGlobalData& globalData) + { + if (LIKELY(hasIndexedProperties(structure()->indexingType()))) + return m_butterfly; + + return ensureIndexedStorageSlow(globalData); + } + static size_t offsetOfInlineStorage(); static ptrdiff_t butterflyOffset() @@ -749,47 +661,19 @@ protected: return 0; } } - - Butterfly* createInitialUndecided(JSGlobalData&, unsigned length); - WriteBarrier<Unknown>* createInitialInt32(JSGlobalData&, unsigned length); - double* createInitialDouble(JSGlobalData&, unsigned length); - WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length); - - void convertUndecidedForValue(JSGlobalData&, JSValue); - void convertInt32ForValue(JSGlobalData&, JSValue); - + ArrayStorage* createArrayStorage(JSGlobalData&, unsigned length, unsigned vectorLength); ArrayStorage* createInitialArrayStorage(JSGlobalData&); - - WriteBarrier<Unknown>* convertUndecidedToInt32(JSGlobalData&); - double* convertUndecidedToDouble(JSGlobalData&); - WriteBarrier<Unknown>* convertUndecidedToContiguous(JSGlobalData&); - ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength); - ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&, NonPropertyTransition); - ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&); - - double* convertInt32ToDouble(JSGlobalData&); - WriteBarrier<Unknown>* convertInt32ToContiguous(JSGlobalData&); - ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength); - ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&, NonPropertyTransition); - ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&); - - WriteBarrier<Unknown>* convertDoubleToContiguous(JSGlobalData&); - ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength); - ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&, NonPropertyTransition); - ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&); - + WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length); ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength); ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition); ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&); - ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData&); bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException); - template<IndexingType indexingShape> - void putByIndexBeyondVectorLengthWithoutAttributes(ExecState*, unsigned propertyName, JSValue); + void putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState*, unsigned propertyName, JSValue); void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*); bool increaseVectorLength(JSGlobalData&, unsigned newLength); @@ -803,33 +687,24 @@ protected: // Call this if you want setIndexQuickly to succeed and you're sure that // the array is contiguous. - void ensureLength(JSGlobalData& globalData, unsigned length) + void ensureContiguousLength(JSGlobalData& globalData, unsigned length) { ASSERT(length < MAX_ARRAY_INDEX); - ASSERT(hasContiguous(structure()->indexingType()) || hasInt32(structure()->indexingType()) || hasDouble(structure()->indexingType()) || hasUndecided(structure()->indexingType())); + ASSERT(hasContiguous(structure()->indexingType())); if (m_butterfly->vectorLength() < length) - ensureLengthSlow(globalData, length); + ensureContiguousLengthSlow(globalData, length); if (m_butterfly->publicLength() < length) m_butterfly->setPublicLength(length); } - template<IndexingType indexingShape> - unsigned countElements(Butterfly*); + unsigned countElementsInContiguous(Butterfly*); - // This is relevant to undecided, int32, double, and contiguous. - unsigned countElements(); - - // This strange method returns a pointer to the start of the indexed data - // as if it contained JSValues. But it won't always contain JSValues. - // Make sure you cast this to the appropriate type before using. template<IndexingType indexingType> WriteBarrier<Unknown>* indexingData() { switch (indexingType) { - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return m_butterfly->contiguous(); @@ -845,7 +720,6 @@ protected: WriteBarrier<Unknown>* currentIndexingData() { switch (structure()->indexingType()) { - case ALL_INT32_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return m_butterfly->contiguous(); @@ -858,32 +732,10 @@ protected: } } - JSValue getHolyIndexQuickly(unsigned i) - { - switch (structure()->indexingType()) { - case ALL_INT32_INDEXING_TYPES: - case ALL_CONTIGUOUS_INDEXING_TYPES: - return m_butterfly->contiguous()[i].get(); - case ALL_DOUBLE_INDEXING_TYPES: { - double value = m_butterfly->contiguousDouble()[i]; - if (value == value) - return JSValue(JSValue::EncodeAsDouble, value); - return JSValue(); - } - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return m_butterfly->arrayStorage()->m_vector[i].get(); - default: - CRASH(); - return JSValue(); - } - } - template<IndexingType indexingType> unsigned relevantLength() { switch (indexingType) { - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return m_butterfly->publicLength(); @@ -901,8 +753,6 @@ protected: unsigned currentRelevantLength() { switch (structure()->indexingType()) { - case ALL_INT32_INDEXING_TYPES: - case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: return m_butterfly->publicLength(); @@ -928,8 +778,6 @@ private: void isObject(); void isString(); - Butterfly* createInitialIndexedStorage(JSGlobalData&, unsigned length, size_t elementSize); - ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(JSGlobalData&, ArrayStorage*); template<PutMode> @@ -952,18 +800,11 @@ private: JS_EXPORT_PRIVATE bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&); - ArrayStorage* constructConvertedArrayStorageWithoutCopyingElements(JSGlobalData&, unsigned neededLength); - - JS_EXPORT_PRIVATE void setIndexQuicklyToUndecided(JSGlobalData&, unsigned index, JSValue); - JS_EXPORT_PRIVATE void convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(JSGlobalData&, unsigned index, JSValue); - JS_EXPORT_PRIVATE void convertDoubleToContiguousWhilePerformingSetIndex(JSGlobalData&, unsigned index, JSValue); - - void ensureLengthSlow(JSGlobalData&, unsigned length); + void ensureContiguousLengthSlow(JSGlobalData&, unsigned length); - WriteBarrier<Unknown>* ensureInt32Slow(JSGlobalData&); - double* ensureDoubleSlow(JSGlobalData&); WriteBarrier<Unknown>* ensureContiguousSlow(JSGlobalData&); ArrayStorage* ensureArrayStorageSlow(JSGlobalData&); + Butterfly* ensureIndexedStorageSlow(JSGlobalData&); protected: Butterfly* m_butterfly; diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp index 8f245f98d..e7f8cad17 100644 --- a/Source/JavaScriptCore/runtime/JSValue.cpp +++ b/Source/JavaScriptCore/runtime/JSValue.cpp @@ -215,8 +215,8 @@ char* JSValue::description() const #endif } else if (isCell()) { snprintf( - description, size, "Cell: %p -> %p (%p: %s, %s)", - asCell(), isObject() ? asObject(*this)->butterfly() : 0, asCell()->structure(), asCell()->structure()->classInfo()->className, + description, size, "Cell: %p (%p: %s, %s)", + asCell(), asCell()->structure(), asCell()->structure()->classInfo()->className, indexingTypeToString(asCell()->structure()->indexingTypeIncludingHistory())); } else if (isTrue()) snprintf(description, size, "True"); diff --git a/Source/JavaScriptCore/runtime/JSValueInlines.h b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h index c5a42f67f..224982e9e 100644 --- a/Source/JavaScriptCore/runtime/JSValueInlines.h +++ b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSValueInlines_h -#define JSValueInlines_h +#ifndef JSValueInlineMethods_h +#define JSValueInlineMethods_h #include "JSValue.h" @@ -493,5 +493,4 @@ namespace JSC { } // namespace JSC -#endif // JSValueInlines_h - +#endif // JSValueInlineMethods_h diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp index bf27327bf..cd854417b 100644 --- a/Source/JavaScriptCore/runtime/LiteralParser.cpp +++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp @@ -27,8 +27,8 @@ #include "config.h" #include "LiteralParser.h" -#include "ButterflyInlines.h" -#include "CopiedSpaceInlines.h" +#include "ButterflyInlineMethods.h" +#include "CopiedSpaceInlineMethods.h" #include "JSArray.h" #include "JSString.h" #include "Lexer.h" @@ -548,7 +548,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) switch(state) { startParseArray: case StartParseArray: { - JSArray* array = constructEmptyArray(m_exec, 0); + JSArray* array = constructEmptyArray(m_exec); objectStack.append(array); // fallthrough } diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp index 7e74a914b..7df047d28 100644 --- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -21,8 +21,8 @@ #include "config.h" #include "ObjectConstructor.h" -#include "ButterflyInlines.h" -#include "CopiedSpaceInlines.h" +#include "ButterflyInlineMethods.h" +#include "CopiedSpaceInlineMethods.h" #include "Error.h" #include "ExceptionHelpers.h" #include "JSFunction.h" @@ -182,7 +182,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exe return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object."))); PropertyNameArray properties(exec); asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties); - JSArray* names = constructEmptyArray(exec, 0); + JSArray* names = constructEmptyArray(exec); size_t numProperties = properties.size(); for (size_t i = 0; i < numProperties; i++) names->push(exec, jsOwnedString(exec, properties[i].string())); @@ -196,7 +196,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec) return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object."))); PropertyNameArray properties(exec); asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties); - JSArray* keys = constructEmptyArray(exec, 0); + JSArray* keys = constructEmptyArray(exec); size_t numProperties = properties.size(); for (size_t i = 0; i < numProperties; i++) keys->push(exec, jsOwnedString(exec, properties[i].string())); diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h index ed14e895f..01df7e98c 100644 --- a/Source/JavaScriptCore/runtime/Operations.h +++ b/Source/JavaScriptCore/runtime/Operations.h @@ -26,7 +26,7 @@ #include "Interpreter.h" #include "JSProxy.h" #include "JSString.h" -#include "JSValueInlines.h" +#include "JSValueInlineMethods.h" namespace JSC { diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp index 19f3b81ad..ce9c2d2db 100644 --- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp +++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp @@ -26,7 +26,7 @@ #include "config.h" #include "RegExpMatchesArray.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" namespace JSC { diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp index 00dd1ed74..35de40912 100644 --- a/Source/JavaScriptCore/runtime/RegExpObject.cpp +++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp @@ -21,8 +21,8 @@ #include "config.h" #include "RegExpObject.h" -#include "ButterflyInlines.h" -#include "CopiedSpaceInlines.h" +#include "ButterflyInlineMethods.h" +#include "CopiedSpaceInlineMethods.h" #include "Error.h" #include "ExceptionHelpers.h" #include "JSArray.h" diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp index 93009d806..5aafe8bb3 100644 --- a/Source/JavaScriptCore/runtime/StringPrototype.cpp +++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp @@ -22,9 +22,9 @@ #include "config.h" #include "StringPrototype.h" -#include "ButterflyInlines.h" +#include "ButterflyInlineMethods.h" #include "CachedCall.h" -#include "CopiedSpaceInlines.h" +#include "CopiedSpaceInlineMethods.h" #include "Error.h" #include "Executable.h" #include "JSGlobalObjectFunctions.h" @@ -870,7 +870,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec) return JSValue::encode(jsNull()); } - return JSValue::encode(constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list)); + return JSValue::encode(constructArray(exec, list)); } EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec) @@ -973,7 +973,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // 3. Let A be a new array created as if by the expression new Array() // where Array is the standard built-in constructor with that name. - JSArray* result = constructEmptyArray(exec, 0); + JSArray* result = constructEmptyArray(exec); // 4. Let lengthA be 0. unsigned resultLength = 0; @@ -1388,10 +1388,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec) return throwVMTypeError(exec); String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); - String color = a0.toWTFString(exec); - color.replaceWithLiteral('"', """); - - return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", color, "\">", s, "</font>")); + return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec)->value(exec), "\">", s, "</font>")); } EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec) @@ -1436,10 +1433,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec) return JSValue::encode(jsNontrivialString(exec, impl)); } - String fontSize = a0.toWTFString(exec); - fontSize.replaceWithLiteral('"', """); - - return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", fontSize, "\">", s, "</font>")); + return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec)->value(exec), "\">", s, "</font>")); } EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec) @@ -1449,10 +1443,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec) return throwVMTypeError(exec); String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); - String anchor = a0.toWTFString(exec); - anchor.replaceWithLiteral('"', """); - - return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", anchor, "\">", s, "</a>")); + return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec)->value(exec), "\">", s, "</a>")); } EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec) @@ -1462,8 +1453,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec) return throwVMTypeError(exec); String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); - String linkText = a0.toWTFString(exec); - linkText.replaceWithLiteral('"', """); + String linkText = a0.toString(exec)->value(exec); unsigned linkTextSize = linkText.length(); unsigned stringSize = s.length(); diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp index e930c022a..e733c7e23 100644 --- a/Source/JavaScriptCore/runtime/Structure.cpp +++ b/Source/JavaScriptCore/runtime/Structure.cpp @@ -543,13 +543,12 @@ Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure* unsigned attributes = toAttributes(transitionKind); IndexingType indexingType = newIndexingType(structure->indexingTypeIncludingHistory(), transitionKind); - if (JSGlobalObject* globalObject = structure->m_globalObject.get()) { - if (globalObject->isOriginalArrayStructure(structure)) { - Structure* result = globalObject->originalArrayStructureForIndexingType(indexingType); - if (result->indexingTypeIncludingHistory() == indexingType) { - structure->notifyTransitionFromThisStructure(); - return result; - } + JSGlobalObject* globalObject = structure->globalObject(); + if (structure == globalObject->arrayStructure()) { + Structure* transition = globalObject->arrayStructureWithArrayStorage(); + if (transition->indexingTypeIncludingHistory() == indexingType) { + structure->notifyTransitionFromThisStructure(); + return transition; } } diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h index 5291ed540..3ab7b2014 100644 --- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h @@ -43,9 +43,6 @@ static const unsigned FirstInternalAttribute = 1 << 6; // Use for transitions th // Support for attributes used to indicate transitions not related to properties. // If any of these are used, the string portion of the key should be 0. enum NonPropertyTransition { - AllocateUndecided, - AllocateInt32, - AllocateDouble, AllocateContiguous, AllocateArrayStorage, AllocateSlowPutArrayStorage, @@ -61,23 +58,14 @@ inline unsigned toAttributes(NonPropertyTransition transition) inline IndexingType newIndexingType(IndexingType oldType, NonPropertyTransition transition) { switch (transition) { - case AllocateUndecided: - ASSERT(!hasIndexedProperties(oldType)); - return oldType | UndecidedShape; - case AllocateInt32: - ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType)); - return (oldType & ~IndexingShapeMask) | Int32Shape; - case AllocateDouble: - ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType)); - return (oldType & ~IndexingShapeMask) | DoubleShape; case AllocateContiguous: - ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType) || hasDouble(oldType)); - return (oldType & ~IndexingShapeMask) | ContiguousShape; + ASSERT(!hasIndexedProperties(oldType)); + return oldType | ContiguousShape; case AllocateArrayStorage: - ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType) || hasDouble(oldType) || hasContiguous(oldType)); + ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType)); return (oldType & ~IndexingShapeMask) | ArrayStorageShape; case AllocateSlowPutArrayStorage: - ASSERT(!hasIndexedProperties(oldType) || hasUndecided(oldType) || hasInt32(oldType) || hasDouble(oldType) || hasContiguous(oldType) || hasContiguous(oldType)); + ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType)); return (oldType & ~IndexingShapeMask) | SlowPutArrayStorageShape; case SwitchToSlowPutArrayStorage: ASSERT(hasFastArrayStorage(oldType)); |