Changeset 174226 in webkit
- Timestamp:
- Oct 2, 2014, 1:35:58 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 44 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r174224 r174226 1 2014-10-01 Oliver Hunt <oliver@apple.com> 2 3 Do all closed variable access through the local lexical object 4 https://bugs.webkit.org/show_bug.cgi?id=136869 5 6 Reviewed by Filip Pizlo. 7 8 This patch makes all reads and writes from captured registers 9 go through the lexical record, and by doing so removes the 10 need for record tearoff. 11 12 To keep the patch simple we still number variables as though 13 they are local stack allocated registers, but ::local() will 14 fail. When local fails we perform a generic resolve, and in 15 that resolve we now use a ResolveScopeInfo struct to pass 16 around information about whether a lookup is a statically 17 known captured variable, and its location in the activation. 18 To ensure correct behaviour during codeblock linking we also 19 add a LocalClosureVariable resolution type. 20 21 To ensure correct semantics for the Arguments object, we now 22 have to eagerly create the Arguments object for any function 23 that uses both the Arguments object and requires a lexical 24 record. 25 26 * bytecode/BytecodeList.json: 27 * bytecode/BytecodeUseDef.h: 28 (JSC::computeUsesForBytecodeOffset): 29 (JSC::computeDefsForBytecodeOffset): 30 * bytecode/CodeBlock.cpp: 31 (JSC::CodeBlock::dumpBytecode): 32 (JSC::CodeBlock::CodeBlock): 33 (JSC::CodeBlock::finalizeUnconditionally): 34 * bytecompiler/BytecodeGenerator.cpp: 35 (JSC::BytecodeGenerator::BytecodeGenerator): 36 (JSC::BytecodeGenerator::initializeCapturedVariable): 37 During the entry to a function we are not yet in a position 38 to allocate temporaries so we directly use the lexical 39 environment register. 40 (JSC::BytecodeGenerator::resolveCallee): 41 (JSC::BytecodeGenerator::emitMove): 42 (JSC::BytecodeGenerator::local): 43 (JSC::BytecodeGenerator::constLocal): 44 (JSC::BytecodeGenerator::emitResolveScope): 45 (JSC::BytecodeGenerator::emitResolveConstantLocal): 46 The two resolve scope operations could technically skip 47 the op_resolve_scope, and simply perform 48 op_mov dst, recordRegister 49 but for now it seemed best to maintain the same basic 50 behaviour. 51 (JSC::BytecodeGenerator::emitGetFromScope): 52 (JSC::BytecodeGenerator::emitPutToScope): 53 (JSC::BytecodeGenerator::createArgumentsIfNecessary): 54 If we have an environment we've already created Arguments 55 so no need to check again. 56 (JSC::BytecodeGenerator::emitReturn): 57 Don't need to emit tearoff_environment 58 * bytecompiler/BytecodeGenerator.h: 59 (JSC::Local::Local): 60 (JSC::Local::operator bool): 61 (JSC::Local::get): 62 (JSC::Local::isReadOnly): 63 (JSC::Local::isSpecial): 64 (JSC::ResolveScopeInfo::ResolveScopeInfo): 65 (JSC::ResolveScopeInfo::isLocal): 66 (JSC::ResolveScopeInfo::localIndex): 67 (JSC::BytecodeGenerator::shouldCreateArgumentsEagerly): 68 (JSC::Local::isCaptured): Deleted. 69 (JSC::Local::captureMode): Deleted. 70 * bytecompiler/NodesCodegen.cpp: 71 (JSC::ResolveNode::emitBytecode): 72 (JSC::EvalFunctionCallNode::emitBytecode): 73 (JSC::FunctionCallResolveNode::emitBytecode): 74 (JSC::PostfixNode::emitResolve): 75 (JSC::DeleteResolveNode::emitBytecode): 76 (JSC::TypeOfResolveNode::emitBytecode): 77 (JSC::PrefixNode::emitResolve): 78 (JSC::ReadModifyResolveNode::emitBytecode): 79 (JSC::AssignResolveNode::emitBytecode): 80 (JSC::ConstDeclNode::emitCodeSingle): 81 (JSC::EmptyVarExpression::emitBytecode): 82 (JSC::ForInNode::tryGetBoundLocal): 83 (JSC::ForInNode::emitLoopHeader): 84 (JSC::ForOfNode::emitBytecode): 85 (JSC::BindingNode::bindValue): 86 * dfg/DFGAbstractInterpreterInlines.h: 87 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 88 * dfg/DFGByteCodeParser.cpp: 89 (JSC::DFG::ByteCodeParser::parseBlock): 90 * dfg/DFGCapabilities.cpp: 91 (JSC::DFG::capabilityLevel): 92 * dfg/DFGClobberize.h: 93 (JSC::DFG::clobberize): 94 * dfg/DFGDoesGC.cpp: 95 (JSC::DFG::doesGC): 96 * dfg/DFGFixupPhase.cpp: 97 (JSC::DFG::FixupPhase::fixupNode): 98 * dfg/DFGGraph.cpp: 99 (JSC::DFG::Graph::tryGetRegisters): 100 * dfg/DFGNodeType.h: 101 * dfg/DFGPredictionPropagationPhase.cpp: 102 (JSC::DFG::PredictionPropagationPhase::propagate): 103 * dfg/DFGSafeToExecute.h: 104 (JSC::DFG::safeToExecute): 105 * dfg/DFGSpeculativeJIT32_64.cpp: 106 (JSC::DFG::SpeculativeJIT::compile): 107 * dfg/DFGSpeculativeJIT64.cpp: 108 (JSC::DFG::SpeculativeJIT::compile): 109 * ftl/FTLCapabilities.cpp: 110 (JSC::FTL::canCompile): 111 * interpreter/Interpreter.cpp: 112 (JSC::unwindCallFrame): 113 * jit/JIT.cpp: 114 (JSC::JIT::privateCompileMainPass): 115 (JSC::JIT::privateCompileSlowCases): 116 * jit/JIT.h: 117 * jit/JITOpcodes.cpp: 118 (JSC::JIT::emit_op_captured_mov): Deleted. 119 (JSC::JIT::emit_op_tear_off_lexical_environment): Deleted. 120 (JSC::JIT::emitSlow_op_captured_mov): Deleted. 121 * jit/JITOpcodes32_64.cpp: 122 (JSC::JIT::emit_op_captured_mov): Deleted. 123 (JSC::JIT::emit_op_tear_off_lexical_environment): Deleted. 124 * jit/JITOperations.cpp: 125 * jit/JITOperations.h: 126 * jit/JITPropertyAccess.cpp: 127 (JSC::JIT::emit_op_resolve_scope): 128 (JSC::JIT::emit_op_get_from_scope): 129 (JSC::JIT::emitPutClosureVar): 130 (JSC::JIT::emit_op_put_to_scope): 131 (JSC::JIT::emitSlow_op_put_to_scope): 132 * jit/JITPropertyAccess32_64.cpp: 133 (JSC::JIT::emit_op_resolve_scope): 134 (JSC::JIT::emit_op_get_from_scope): 135 (JSC::JIT::emitPutClosureVar): 136 (JSC::JIT::emit_op_put_to_scope): 137 (JSC::JIT::emitSlow_op_put_to_scope): 138 * llint/LLIntData.cpp: 139 (JSC::LLInt::Data::performAssertions): 140 * llint/LLIntSlowPaths.cpp: 141 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 142 * llint/LLIntSlowPaths.h: 143 * llint/LowLevelInterpreter.asm: 144 * llint/LowLevelInterpreter32_64.asm: 145 * llint/LowLevelInterpreter64.asm: 146 * runtime/Arguments.cpp: 147 (JSC::Arguments::tearOff): 148 * runtime/Arguments.h: 149 (JSC::Arguments::argument): 150 * runtime/CommonSlowPaths.cpp: 151 (JSC::SLOW_PATH_DECL): Deleted. 152 * runtime/CommonSlowPaths.h: 153 * runtime/JSLexicalEnvironment.cpp: 154 (JSC::JSLexicalEnvironment::visitChildren): 155 (JSC::JSLexicalEnvironment::symbolTableGet): 156 (JSC::JSLexicalEnvironment::symbolTablePut): 157 (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames): 158 (JSC::JSLexicalEnvironment::getOwnPropertySlot): 159 (JSC::JSLexicalEnvironment::argumentsGetter): 160 * runtime/JSLexicalEnvironment.h: 161 (JSC::JSLexicalEnvironment::create): 162 (JSC::JSLexicalEnvironment::JSLexicalEnvironment): 163 (JSC::JSLexicalEnvironment::tearOff): Deleted. 164 (JSC::JSLexicalEnvironment::isTornOff): Deleted. 165 * runtime/JSScope.cpp: 166 (JSC::resolveTypeName): 167 * runtime/JSScope.h: 168 (JSC::makeType): 169 (JSC::needsVarInjectionChecks): 170 * runtime/WriteBarrier.h: 171 (JSC::WriteBarrier<Unknown>::WriteBarrier): 172 1 173 2014-10-02 Filip Pizlo <fpizlo@apple.com> 2 174 -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r174216 r174226 18 18 { "name" : "op_new_regexp", "length" : 3 }, 19 19 { "name" : "op_mov", "length" : 3 }, 20 { "name" : "op_captured_mov", "length" : 4 },21 20 { "name" : "op_not", "length" : 3 }, 22 21 { "name" : "op_eq", "length" : 4 }, … … 100 99 { "name" : "op_call_eval", "length" : 9 }, 101 100 { "name" : "op_call_varargs", "length" : 9 }, 102 { "name" : "op_tear_off_lexical_environment", "length" : 2 },103 101 { "name" : "op_tear_off_arguments", "length" : 3 }, 104 102 { "name" : "op_ret", "length" : 2 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r173517 r174226 63 63 case op_create_arguments: 64 64 case op_to_this: 65 case op_tear_off_lexical_environment:66 65 case op_profile_will_call: 67 66 case op_profile_did_call: … … 142 141 case op_not: 143 142 case op_mov: 144 case op_captured_mov:145 143 case op_new_array_with_size: 146 144 case op_create_this: … … 306 304 case op_resolve_scope: 307 305 case op_strcat: 308 case op_tear_off_lexical_environment:309 306 case op_to_primitive: 310 307 case op_catch: … … 366 363 case op_not: 367 364 case op_mov: 368 case op_captured_mov:369 365 case op_new_object: 370 366 case op_to_this: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r173797 r174226 834 834 break; 835 835 } 836 case op_captured_mov: {837 int r0 = (++it)->u.operand;838 int r1 = (++it)->u.operand;839 printLocationAndOp(out, exec, location, it, "captured_mov");840 out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());841 ++it;842 break;843 }844 836 case op_profile_type: { 845 837 int r0 = (++it)->u.operand; … … 1317 1309 break; 1318 1310 } 1319 1320 case op_tear_off_lexical_environment: { 1321 int r0 = (++it)->u.operand; 1322 printLocationOpAndRegisterOperand(out, exec, location, it, "tear_off_lexical_environment", r0); 1323 break; 1324 } 1311 1325 1312 case op_tear_off_arguments: { 1326 1313 int r0 = (++it)->u.operand; … … 1947 1934 const Identifier& ident = identifier(pc[2].u.operand); 1948 1935 ResolveType type = static_cast<ResolveType>(pc[3].u.operand); 1936 if (type == LocalClosureVar) { 1937 instructions[i + 3].u.operand = ClosureVar; 1938 break; 1939 } 1949 1940 1950 1941 ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, type); … … 1963 1954 1964 1955 // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand 1956 1965 1957 const Identifier& ident = identifier(pc[3].u.operand); 1966 1958 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand); 1959 if (modeAndType.type() == LocalClosureVar) { 1960 instructions[i + 4] = ResolveModeAndType(modeAndType.mode(), ClosureVar).operand(); 1961 break; 1962 } 1963 1967 1964 ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, modeAndType.type()); 1968 1965 … … 1980 1977 // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand 1981 1978 const Identifier& ident = identifier(pc[2].u.operand); 1979 1982 1980 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand); 1981 if (modeAndType.type() == LocalClosureVar) { 1982 if (pc[5].u.index == UINT_MAX) { 1983 instructions[i + 5].u.watchpointSet = 0; 1984 break; 1985 } 1986 StringImpl* uid = identifier(pc[5].u.index).impl(); 1987 RELEASE_ASSERT(didCloneSymbolTable); 1988 if (ident != m_vm->propertyNames->arguments) { 1989 ConcurrentJITLocker locker(m_symbolTable->m_lock); 1990 SymbolTable::Map::iterator iter = m_symbolTable->find(locker, uid); 1991 ASSERT(iter != m_symbolTable->end(locker)); 1992 iter->value.prepareToWatch(symbolTable()); 1993 instructions[i + 5].u.watchpointSet = iter->value.watchpointSet(); 1994 } else 1995 instructions[i + 5].u.watchpointSet = nullptr; 1996 break; 1997 } 1998 1983 1999 ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Put, modeAndType.type()); 1984 2000 … … 2032 2048 break; 2033 2049 } 2050 case ProfileTypeBytecodePutToLocalScope: 2051 case ProfileTypeBytecodeGetFromLocalScope: { 2052 const Identifier& ident = identifier(pc[4].u.operand); 2053 symbolTable = m_symbolTable.get(); 2054 ConcurrentJITLocker locker(symbolTable->m_lock); 2055 // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet. 2056 symbolTable->prepareForTypeProfiling(locker); 2057 globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm()); 2058 globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm()); 2059 2060 break; 2061 } 2062 2034 2063 case ProfileTypeBytecodeHasGlobalID: { 2035 2064 symbolTable = m_symbolTable.get(); … … 2076 2105 } 2077 2106 2078 case op_captured_mov:2079 2107 case op_new_captured_func: { 2080 2108 if (pc[3].u.index == UINT_MAX) { … … 2547 2575 ResolveModeAndType modeAndType = 2548 2576 ResolveModeAndType(curInstruction[4].u.operand); 2549 if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks )2577 if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks || modeAndType.type() == LocalClosureVar) 2550 2578 continue; 2551 2579 WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure; … … 3869 3897 switch (opcodeID) { 3870 3898 case op_enter: 3871 case op_captured_mov:3872 3899 case op_init_lazy_reg: 3873 3900 case op_create_arguments: … … 3877 3904 break; 3878 3905 } 3879 3906 3880 3907 VirtualRegister virtualReg(operand); 3881 3908 if (!virtualReg.isLocal()) 3882 3909 return; 3883 3910 3911 if (codeBlock->usesArguments() && virtualReg == codeBlock->argumentsRegister()) 3912 return; 3913 3884 3914 if (codeBlock->captureCount() && codeBlock->symbolTable()->isCaptured(operand)) { 3885 3915 codeBlock->beginValidationDidFail(); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r174216 r174226 247 247 if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) { 248 248 m_lexicalEnvironmentRegister = addVar(); 249 emitInitLazyRegister(m_lexicalEnvironmentRegister);250 249 m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister()); 251 250 emitOpcode(op_create_lexical_environment); … … 268 267 emitInitLazyRegister(unmodifiedArgumentsRegister); 269 268 270 if (should TearOffArgumentsEagerly()) {269 if (shouldCreateArgumentsEagerly() || shouldTearOffArgumentsEagerly()) { 271 270 emitOpcode(op_create_arguments); 272 271 instructions().append(argumentsRegister->index()); 272 if (m_codeBlock->hasActivationRegister()) { 273 RegisterID* argumentsRegister = ®isterFor(m_codeBlock->argumentsRegister().offset()); 274 initializeCapturedVariable(argumentsRegister, propertyNames().arguments, argumentsRegister); 275 RegisterID* uncheckedArgumentsRegister = ®isterFor(JSC::unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset()); 276 initializeCapturedVariable(uncheckedArgumentsRegister, propertyNames().arguments, uncheckedArgumentsRegister); 277 } 273 278 } 274 279 } … … 317 322 // Captured variables and functions go first so that activations don't have 318 323 // to step over the non-captured locals to mark them. 319 if (functionBody->hasCapturedVariables() ) {324 if (functionBody->hasCapturedVariables() || shouldCaptureAllTheThings) { 320 325 for (size_t i = 0; i < boundParameterProperties.size(); i++) { 321 326 const Identifier& ident = boundParameterProperties[i]; 322 if (functionBody->captures(ident) )327 if (functionBody->captures(ident) || shouldCaptureAllTheThings) 323 328 addVar(ident, IsVariable, IsWatchable); 324 329 } … … 326 331 FunctionBodyNode* function = functionStack[i]; 327 332 const Identifier& ident = function->ident(); 328 if (functionBody->captures(ident) ) {333 if (functionBody->captures(ident) || shouldCaptureAllTheThings) { 329 334 m_functions.add(ident.impl()); 330 emitNewFunction(addVar(ident, IsVariable, IsWatchable), IsCaptured, function); 335 // We rely on still allocating stack space for captured variables 336 // here. 337 RegisterID* newFunction = emitNewFunction(addVar(ident, IsVariable, IsWatchable), IsCaptured, function); 338 initializeCapturedVariable(newFunction, ident, newFunction); 331 339 } 332 340 } 333 341 for (size_t i = 0; i < varStack.size(); ++i) { 334 342 const Identifier& ident = varStack[i].first; 335 if (functionBody->captures(ident) )343 if (functionBody->captures(ident) || shouldCaptureAllTheThings) 336 344 addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, IsWatchable); 337 345 } … … 342 350 bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks && !m_vm->typeProfiler(); 343 351 m_firstLazyFunction = codeBlock->m_numVars; 344 for (size_t i = 0; i < functionStack.size(); ++i) { 345 FunctionBodyNode* function = functionStack[i]; 346 const Identifier& ident = function->ident(); 347 if (!functionBody->captures(ident)) { 348 m_functions.add(ident.impl()); 349 RefPtr<RegisterID> reg = addVar(ident, IsVariable, NotWatchable); 350 // Don't lazily create functions that override the name 'arguments' 351 // as this would complicate lazy instantiation of actual arguments. 352 if (!canLazilyCreateFunctions || ident == propertyNames().arguments) 353 emitNewFunction(reg.get(), NotCaptured, function); 354 else { 355 emitInitLazyRegister(reg.get()); 356 m_lazyFunctions.set(reg->virtualRegister().toLocal(), function); 352 if (!shouldCaptureAllTheThings) { 353 for (size_t i = 0; i < functionStack.size(); ++i) { 354 FunctionBodyNode* function = functionStack[i]; 355 const Identifier& ident = function->ident(); 356 if (!functionBody->captures(ident)) { 357 m_functions.add(ident.impl()); 358 RefPtr<RegisterID> reg = addVar(ident, IsVariable, NotWatchable); 359 // Don't lazily create functions that override the name 'arguments' 360 // as this would complicate lazy instantiation of actual arguments. 361 if (!canLazilyCreateFunctions || ident == propertyNames().arguments) 362 emitNewFunction(reg.get(), NotCaptured, function); 363 else { 364 emitInitLazyRegister(reg.get()); 365 m_lazyFunctions.set(reg->virtualRegister().toLocal(), function); 366 } 357 367 } 358 368 } 359 } 360 m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction; 361 for (size_t i = 0; i < boundParameterProperties.size(); i++) { 362 const Identifier& ident = boundParameterProperties[i]; 363 if (!functionBody->captures(ident)) 364 addVar(ident, IsVariable, IsWatchable); 365 } 366 for (size_t i = 0; i < varStack.size(); ++i) { 367 const Identifier& ident = varStack[i].first; 368 if (!functionBody->captures(ident)) 369 addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable); 370 } 371 372 if (shouldCaptureAllTheThings) 373 m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset()); 369 m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction; 370 for (size_t i = 0; i < boundParameterProperties.size(); i++) { 371 const Identifier& ident = boundParameterProperties[i]; 372 if (!functionBody->captures(ident)) 373 addVar(ident, IsVariable, IsWatchable); 374 } 375 for (size_t i = 0; i < varStack.size(); ++i) { 376 const Identifier& ident = varStack[i].first; 377 if (!functionBody->captures(ident)) 378 addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable); 379 } 380 } 374 381 375 382 if (m_symbolTable->captureCount()) … … 397 404 index = capturedArguments[i]->index(); 398 405 RegisterID original(nextParameterIndex); 399 emitMove(capturedArguments[i], &original);406 initializeCapturedVariable(capturedArguments[i], simpleParameter->boundProperty(), &original); 400 407 } 401 408 addParameter(simpleParameter->boundProperty(), index); … … 477 484 } 478 485 486 RegisterID* BytecodeGenerator::initializeCapturedVariable(RegisterID* dst, const Identifier& propertyName, RegisterID* value) 487 { 488 489 m_codeBlock->addPropertyAccessInstruction(instructions().size()); 490 emitOpcode(op_put_to_scope); 491 instructions().append(m_lexicalEnvironmentRegister->index()); 492 instructions().append(addConstant(propertyName)); 493 instructions().append(value->index()); 494 instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand()); 495 instructions().append(0); 496 instructions().append(dst->index()); 497 return dst; 498 } 499 479 500 RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode) 480 501 { … … 487 508 m_calleeRegister.setIndex(JSStack::Callee); 488 509 if (functionBodyNode->captures(functionBodyNode->ident())) 489 return emitMove(addVar(), IsCaptured, &m_calleeRegister);510 return initializeCapturedVariable(addVar(), functionBodyNode->ident(), &m_calleeRegister); 490 511 491 512 return &m_calleeRegister; … … 997 1018 } 998 1019 999 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, CaptureMode captureMode,RegisterID* src)1020 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src) 1000 1021 { 1001 1022 m_staticPropertyAnalyzer.mov(dst->index(), src->index()); 1002 1003 emitOpcode( captureMode == IsCaptured ? op_captured_mov :op_mov);1023 ASSERT(dst->virtualRegister() == m_codeBlock->argumentsRegister() || !isCaptured(dst->index())); 1024 emitOpcode(op_mov); 1004 1025 instructions().append(dst->index()); 1005 1026 instructions().append(src->index()); 1006 if (captureMode == IsCaptured)1007 instructions().append(watchableVariable(dst->index()));1008 1027 1009 1028 if (!dst->isTemporary() && vm()->typeProfiler()) … … 1011 1030 1012 1031 return dst; 1013 }1014 1015 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)1016 {1017 return emitMove(dst, captureMode(dst->index()), src);1018 1032 } 1019 1033 … … 1198 1212 { 1199 1213 if (property == propertyNames().thisIdentifier) 1200 return Local(thisRegister(), ReadOnly, NotCaptured);1201 1202 if ( property == propertyNames().arguments)1214 return Local(thisRegister(), ReadOnly, Local::SpecialLocal); 1215 bool isArguments = property == propertyNames().arguments; 1216 if (isArguments) 1203 1217 createArgumentsIfNecessary(); 1204 1218 … … 1210 1224 return Local(); 1211 1225 1226 1212 1227 RegisterID* local = createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); 1213 return Local(local, entry.getAttributes(), captureMode(local->index())); 1228 1229 if (isCaptured(local->index()) && m_lexicalEnvironmentRegister) 1230 return Local(); 1231 1232 return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal); 1214 1233 } 1215 1234 … … 1224 1243 1225 1244 RegisterID* local = createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); 1226 return Local(local, entry.getAttributes(), captureMode(local->index())); 1245 1246 bool isArguments = property == propertyNames().arguments; 1247 if (isCaptured(local->index()) && m_lexicalEnvironmentRegister) 1248 return Local(); 1249 1250 return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal); 1227 1251 } 1228 1252 … … 1248 1272 } 1249 1273 1250 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier& identifier )1274 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info) 1251 1275 { 1252 1276 m_codeBlock->addPropertyAccessInstruction(instructions().size()); 1277 1278 if (m_symbolTable && m_codeType == FunctionCode && !m_localScopeDepth) { 1279 SymbolTableEntry entry = m_symbolTable->get(identifier.impl()); 1280 if (!entry.isNull()) { 1281 emitOpcode(op_resolve_scope); 1282 instructions().append(kill(dst)); 1283 instructions().append(addConstant(identifier)); 1284 instructions().append(LocalClosureVar); 1285 instructions().append(0); 1286 instructions().append(0); 1287 info = ResolveScopeInfo(entry.getIndex()); 1288 return dst; 1289 } 1290 } 1253 1291 1254 1292 ASSERT(!m_symbolTable || !m_symbolTable->contains(identifier.impl()) || resolveType() == Dynamic); … … 1264 1302 } 1265 1303 1266 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier& identifier, ResolveMode resolveMode) 1304 RegisterID* BytecodeGenerator::emitResolveConstantLocal(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info) 1305 { 1306 if (!m_symbolTable || m_codeType != FunctionCode) 1307 return nullptr; 1308 1309 SymbolTableEntry entry = m_symbolTable->get(identifier.impl()); 1310 if (entry.isNull()) 1311 return nullptr; 1312 info = ResolveScopeInfo(entry.getIndex()); 1313 return emitMove(dst, m_lexicalEnvironmentRegister); 1314 1315 } 1316 1317 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier& identifier, ResolveMode resolveMode, const ResolveScopeInfo& info) 1267 1318 { 1268 1319 m_codeBlock->addPropertyAccessInstruction(instructions().size()); … … 1273 1324 instructions().append(scope->index()); 1274 1325 instructions().append(addConstant(identifier)); 1275 instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());1326 instructions().append(ResolveModeAndType(resolveMode, info.isLocal() ? LocalClosureVar : resolveType()).operand()); 1276 1327 instructions().append(0); 1277 instructions().append( 0);1328 instructions().append(info.localIndex()); 1278 1329 instructions().append(profile); 1279 1330 return dst; 1280 1331 } 1281 1332 1282 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier& identifier, RegisterID* value, ResolveMode resolveMode )1333 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier& identifier, RegisterID* value, ResolveMode resolveMode, const ResolveScopeInfo& info) 1283 1334 { 1284 1335 m_codeBlock->addPropertyAccessInstruction(instructions().size()); … … 1289 1340 instructions().append(addConstant(identifier)); 1290 1341 instructions().append(value->index()); 1291 instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand()); 1292 instructions().append(0); 1293 instructions().append(0); 1342 if (info.isLocal()) { 1343 instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand()); 1344 instructions().append(watchableVariable(registerFor(info.localIndex()).index())); 1345 } else { 1346 instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand()); 1347 instructions().append(0); 1348 } 1349 instructions().append(info.localIndex()); 1294 1350 return value; 1295 1351 } … … 1660 1716 return; 1661 1717 1662 if (shouldTearOffArgumentsEagerly() )1718 if (shouldTearOffArgumentsEagerly() || shouldCreateArgumentsEagerly()) 1663 1719 return; 1664 1720 … … 1856 1912 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src) 1857 1913 { 1858 if (m_lexicalEnvironmentRegister) {1859 emitOpcode(op_tear_off_lexical_environment);1860 instructions().append(m_lexicalEnvironmentRegister->index());1861 }1862 1863 1914 if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !isStrictMode()) { 1864 1915 emitOpcode(op_tear_off_arguments); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r173517 r174226 190 190 : m_local(0) 191 191 , m_attributes(0) 192 { 193 } 194 195 Local(RegisterID* local, unsigned attributes, CaptureMode captureMode) 192 , m_kind(NormalLocal) 193 { 194 } 195 196 enum LocalKind { NormalLocal, SpecialLocal }; 197 198 Local(RegisterID* local, unsigned attributes, LocalKind kind) 196 199 : m_local(local) 197 200 , m_attributes(attributes) 198 , m_isCaptured(captureMode == IsCaptured) 199 { 200 } 201 202 operator bool() { return m_local; } 203 204 RegisterID* get() { return m_local; } 205 206 bool isReadOnly() { return m_attributes & ReadOnly; } 207 208 bool isCaptured() { return m_isCaptured; } 209 CaptureMode captureMode() { return isCaptured() ? IsCaptured : NotCaptured; } 201 , m_kind(kind) 202 { 203 } 204 205 operator bool() const { return m_local; } 206 207 RegisterID* get() const { return m_local; } 208 209 bool isReadOnly() const { return m_attributes & ReadOnly; } 210 bool isSpecial() const { return m_kind != NormalLocal; } 210 211 211 212 private: 212 213 RegisterID* m_local; 213 214 unsigned m_attributes; 214 bool m_isCaptured; 215 LocalKind m_kind; 216 }; 217 218 struct ResolveScopeInfo { 219 ResolveScopeInfo() 220 : m_localIndex(0) 221 , m_resolveScopeKind(NonLocalScope) 222 { 223 } 224 225 ResolveScopeInfo(int index) 226 : m_localIndex(index) 227 , m_resolveScopeKind(LocalScope) 228 { 229 } 230 231 bool isLocal() const { return m_resolveScopeKind == LocalScope; } 232 int localIndex() const { return m_localIndex; } 233 234 private: 235 int m_localIndex; 236 enum { LocalScope, NonLocalScope } m_resolveScopeKind; 215 237 }; 216 238 … … 224 246 ProfileTypeBytecodePutToScope, 225 247 ProfileTypeBytecodeGetFromScope, 248 ProfileTypeBytecodePutToLocalScope, 249 ProfileTypeBytecodeGetFromLocalScope, 226 250 ProfileTypeBytecodeHasGlobalID, 227 251 ProfileTypeBytecodeDoesNotHaveGlobalID, … … 432 456 RegisterID* emitNewRegExp(RegisterID* dst, RegExp*); 433 457 434 RegisterID* emitMove(RegisterID* dst, CaptureMode, RegisterID* src);435 458 RegisterID* emitMove(RegisterID* dst, RegisterID* src); 436 459 … … 474 497 475 498 ResolveType resolveType(); 476 RegisterID* emitResolveScope(RegisterID* dst, const Identifier&); 477 RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&, ResolveMode); 478 RegisterID* emitPutToScope(RegisterID* scope, const Identifier&, RegisterID* value, ResolveMode); 499 RegisterID* emitResolveConstantLocal(RegisterID* dst, const Identifier&, ResolveScopeInfo&); 500 RegisterID* emitResolveScope(RegisterID* dst, const Identifier&, ResolveScopeInfo&); 501 RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&, ResolveMode, const ResolveScopeInfo&); 502 RegisterID* emitPutToScope(RegisterID* scope, const Identifier&, RegisterID* value, ResolveMode, const ResolveScopeInfo&); 479 503 480 504 PassRefPtr<Label> emitLabel(Label*); … … 634 658 RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 635 659 RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); 636 660 RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&, RegisterID*); 661 637 662 public: 638 663 JSString* addStringConstant(const Identifier&); … … 670 695 { 671 696 return m_codeType == FunctionCode && isStrictMode() && m_scopeNode->modifiesParameter(); 697 } 698 699 bool shouldCreateArgumentsEagerly() 700 { 701 if (m_codeType != FunctionCode) 702 return false; 703 return m_lexicalEnvironmentRegister && m_codeBlock->usesArguments(); 672 704 } 673 705 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r173125 r174226 169 169 JSTextPosition divot = m_start + m_ident.length(); 170 170 generator.emitExpressionInfo(divot, m_start, divot); 171 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident); 171 ResolveScopeInfo resolveScopeInfo; 172 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo); 172 173 RegisterID* finalDest = generator.finalDestination(dst); 173 RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound );174 RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo); 174 175 if (generator.vm()->typeProfiler()) { 175 generator.emitProfileType(finalDest, ProfileTypeBytecodeGetFromScope, &m_ident);176 generator.emitProfileType(finalDest, resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident); 176 177 generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1)); 177 178 } … … 490 491 JSTextPosition newDivot = divotStart() + 4; 491 492 generator.emitExpressionInfo(newDivot, divotStart(), newDivot); 492 generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval); 493 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound); 493 ResolveScopeInfo resolveScopeInfo; 494 generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval, resolveScopeInfo); 495 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound, resolveScopeInfo); 494 496 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd()); 495 497 } … … 538 540 JSTextPosition newDivot = divotStart() + m_ident.length(); 539 541 generator.emitExpressionInfo(newDivot, divotStart(), newDivot); 540 generator.emitResolveScope(callArguments.thisRegister(), m_ident); 541 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound); 542 ResolveScopeInfo resolveScopeInfo; 543 generator.emitResolveScope(callArguments.thisRegister(), m_ident, resolveScopeInfo); 544 generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound, resolveScopeInfo); 542 545 RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd()); 543 546 if (generator.vm()->typeProfiler()) { … … 803 806 generator.emitReadOnlyExceptionIfNeeded(); 804 807 localReg = generator.emitMove(generator.tempDestination(dst), localReg); 805 } else if ( local.isCaptured() ||generator.vm()->typeProfiler()) {808 } else if (generator.vm()->typeProfiler()) { 806 809 RefPtr<RegisterID> tempDst = generator.finalDestination(dst); 807 810 ASSERT(dst != localReg); … … 819 822 820 823 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 821 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), ident); 822 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound); 824 ResolveScopeInfo resolveScopeInfo; 825 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo); 826 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo); 823 827 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator); 824 generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound );828 generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo); 825 829 if (generator.vm()->typeProfiler()) { 826 generator.emitProfileType(value.get(), ProfileTypeBytecodePutToScope, &ident);830 generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident); 827 831 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd()); 828 832 } … … 904 908 905 909 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 906 RefPtr<RegisterID> base = generator.emitResolveScope(generator.tempDestination(dst), m_ident); 910 ResolveScopeInfo resolveScopeInfo; 911 RefPtr<RegisterID> base = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo); 907 912 return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident); 908 913 } … … 961 966 } 962 967 963 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident); 964 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound); 968 ResolveScopeInfo resolveScopeInfo; 969 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo); 970 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo); 965 971 if (dst == generator.ignoredResult()) 966 972 return 0; … … 993 999 generator.emitReadOnlyExceptionIfNeeded(); 994 1000 localReg = generator.emitMove(generator.tempDestination(dst), localReg); 995 } else if ( local.isCaptured() ||generator.vm()->typeProfiler()) {1001 } else if (generator.vm()->typeProfiler()) { 996 1002 RefPtr<RegisterID> tempDst = generator.tempDestination(dst); 997 1003 generator.emitMove(tempDst.get(), localReg); … … 1007 1013 1008 1014 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1009 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), ident); 1010 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound); 1015 ResolveScopeInfo resolveScopeInfo; 1016 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.tempDestination(dst), ident, resolveScopeInfo); 1017 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo); 1011 1018 emitIncOrDec(generator, value.get(), m_operator); 1012 generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound );1019 generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo); 1013 1020 if (generator.vm()->typeProfiler()) { 1014 generator.emitProfileType(value.get(), ProfileTypeBytecodePutToScope, &ident);1021 generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident); 1015 1022 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd()); 1016 1023 } … … 1506 1513 } 1507 1514 1508 if (local.isCaptured() 1509 || generator.vm()->typeProfiler() 1515 if (generator.vm()->typeProfiler() 1510 1516 || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) { 1511 1517 RefPtr<RegisterID> result = generator.newTemporary(); … … 1525 1531 1526 1532 generator.emitExpressionInfo(newDivot, divotStart(), newDivot); 1527 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident); 1528 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound); 1533 ResolveScopeInfo resolveScopeInfo; 1534 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo); 1535 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo); 1529 1536 RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this); 1530 RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound );1537 RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound, resolveScopeInfo); 1531 1538 if (generator.vm()->typeProfiler()) { 1532 generator.emitProfileType(result.get(), ProfileTypeBytecodePutToScope, &m_ident);1539 generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident); 1533 1540 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd()); 1534 1541 } … … 1545 1552 return generator.emitNode(dst, m_right); 1546 1553 } 1547 if (local.is Captured() || generator.vm()->typeProfiler()) {1554 if (local.isSpecial() || generator.vm()->typeProfiler()) { 1548 1555 RefPtr<RegisterID> tempDst = generator.tempDestination(dst); 1549 1556 generator.emitNode(tempDst.get(), m_right); … … 1561 1568 if (generator.isStrictMode()) 1562 1569 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1563 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident); 1570 ResolveScopeInfo resolveScopeInfo; 1571 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo); 1564 1572 if (dst == generator.ignoredResult()) 1565 1573 dst = 0; 1566 1574 RefPtr<RegisterID> result = generator.emitNode(dst, m_right); 1567 1575 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1568 RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound );1576 RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo); 1569 1577 if (generator.vm()->typeProfiler()) { 1570 generator.emitProfileType(result.get(), ProfileTypeBytecodePutToScope, &m_ident);1578 generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident); 1571 1579 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd()); 1572 1580 } … … 1677 1685 1678 1686 // FIXME: Maybe call emitExpressionInfo here. 1679 if (local.is Captured() || generator.vm()->typeProfiler()) {1687 if (local.isSpecial() || generator.vm()->typeProfiler()) { 1680 1688 RefPtr<RegisterID> tempDst = generator.newTemporary(); 1681 1689 generator.emitNode(tempDst.get(), m_init); … … 1691 1699 return generator.emitInitGlobalConst(m_ident, value.get()); 1692 1700 1693 if (generator.codeType() != EvalCode) 1701 if (generator.codeType() != EvalCode) { 1702 1703 ResolveScopeInfo resolveScopeInfo; 1704 if (RefPtr<RegisterID> scope = generator.emitResolveConstantLocal(generator.newTemporary(), m_ident, resolveScopeInfo)) 1705 return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo); 1706 1694 1707 return value.get(); 1708 } 1695 1709 1696 1710 // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope. 1697 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident); 1698 return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound); 1711 ResolveScopeInfo resolveScopeInfo; 1712 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo); 1713 return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo); 1699 1714 } 1700 1715 … … 1793 1808 generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr); 1794 1809 else { 1795 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident); 1796 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound); 1797 generator.emitProfileType(value.get(), ProfileTypeBytecodeGetFromScope, &m_ident); 1810 ResolveScopeInfo resolveScopeInfo; 1811 RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo); 1812 RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo); 1813 generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident); 1798 1814 } 1799 1815 … … 1956 1972 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); 1957 1973 Local local = generator.local(ident); 1958 if (local.isCaptured())1959 return nullptr;1960 1974 return local.get(); 1961 1975 } … … 1970 1984 const Identifier& ident = simpleBinding->boundProperty(); 1971 1985 Local local = generator.local(ident); 1972 if (local.is Captured())1986 if (local.isSpecial()) 1973 1987 return nullptr; 1974 1988 return local.get(); … … 1988 2002 if (generator.isStrictMode()) 1989 2003 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1990 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident); 2004 ResolveScopeInfo resolveScopeInfo; 2005 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo); 1991 2006 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1992 generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound );2007 generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo); 1993 2008 } 1994 2009 return; … … 2022 2037 const Identifier& ident = simpleBinding->boundProperty(); 2023 2038 Local local = generator.local(ident); 2024 if (!local.get() || local.is Captured()) {2039 if (!local.get() || local.isSpecial()) { 2025 2040 assignNode->bindings()->bindValue(generator, propertyName); 2026 2041 return; … … 2184 2199 if (generator.isStrictMode()) 2185 2200 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2186 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident); 2201 ResolveScopeInfo resolveScopeInfo; 2202 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo); 2187 2203 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2188 generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound );2204 generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo); 2189 2205 } 2190 2206 } else if (m_lexpr->isDotAccessorNode()) { … … 2823 2839 if (generator.isStrictMode()) 2824 2840 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd()); 2825 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty); 2841 ResolveScopeInfo resolveScopeInfo; 2842 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty, resolveScopeInfo); 2826 2843 generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd()); 2827 generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound );2844 generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo); 2828 2845 if (generator.vm()->typeProfiler()) { 2829 generator.emitProfileType(value, ProfileTypeBytecodePutToScope, &m_boundProperty);2846 generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty); 2830 2847 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd()); 2831 2848 } -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r174167 r174226 1300 1300 break; 1301 1301 1302 case TearOffActivation:1303 1302 case TearOffArguments: 1304 1303 // Does nothing that is user-visible. -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r174167 r174226 2631 2631 NEXT_OPCODE(op_mov); 2632 2632 } 2633 2634 case op_captured_mov: {2635 Node* op = get(VirtualRegister(currentInstruction[2].u.operand));2636 if (VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet) {2637 if (set->state() != IsInvalidated)2638 addToGraph(NotifyWrite, OpInfo(set), op);2639 }2640 set(VirtualRegister(currentInstruction[1].u.operand), op);2641 NEXT_OPCODE(op_captured_mov);2642 }2643 2633 2644 2634 case op_check_has_instance: … … 3197 3187 set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop->m_codeBlock->globalObject())); 3198 3188 break; 3189 case LocalClosureVar: 3199 3190 case ClosureVar: 3200 3191 case ClosureVarWithVarInjectionChecks: { … … 3272 3263 break; 3273 3264 } 3265 case LocalClosureVar: 3274 3266 case ClosureVar: 3275 3267 case ClosureVarWithVarInjectionChecks: { … … 3315 3307 { 3316 3308 ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock); 3317 if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks )3309 if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar) 3318 3310 watchpoints = currentInstruction[5].u.watchpointSet; 3319 3311 else … … 3354 3346 break; 3355 3347 } 3348 case LocalClosureVar: 3356 3349 case ClosureVar: 3357 3350 case ClosureVarWithVarInjectionChecks: { 3358 3351 Node* scopeNode = get(VirtualRegister(scope)); 3359 3352 Node* scopeRegisters = addToGraph(GetClosureRegisters, scopeNode); 3360 addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, get(VirtualRegister(value))); 3353 Node* valueNode = get(VirtualRegister(value)); 3354 3355 if (watchpoints && watchpoints->state() != IsInvalidated) 3356 addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode); 3357 3358 addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, valueNode); 3361 3359 break; 3362 3360 } … … 3406 3404 set(unmodifiedArgumentsRegister(VirtualRegister(currentInstruction[1].u.operand)), createArguments); 3407 3405 NEXT_OPCODE(op_create_arguments); 3408 }3409 3410 case op_tear_off_lexical_environment: {3411 addToGraph(TearOffActivation, get(VirtualRegister(currentInstruction[1].u.operand)));3412 NEXT_OPCODE(op_tear_off_lexical_environment);3413 3406 } 3414 3407 -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r174167 r174226 123 123 case op_profile_type: 124 124 case op_mov: 125 case op_captured_mov:126 125 case op_check_has_instance: 127 126 case op_instanceof: … … 233 232 case op_new_regexp: 234 233 case op_create_lexical_environment: 235 case op_tear_off_lexical_environment:236 234 case op_new_func: 237 235 case op_new_captured_func: -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r174167 r174226 849 849 return; 850 850 } 851 852 case TearOffActivation:853 read(Variables);854 write(JSEnvironmentRecord_registers);855 return;856 851 857 852 case TearOffArguments: -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r174167 r174226 139 139 case ToString: 140 140 case In: 141 case TearOffActivation:142 141 case PhantomArguments: 143 142 case TearOffArguments: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r174167 r174226 1037 1037 SpecNone, StoreBarrier, m_currentNode->origin, 1038 1038 Edge(globalObjectNode, KnownCellUse)); 1039 m_insertionSet.insert(m_indexInBlock, barrierNode);1040 break;1041 }1042 1043 case TearOffActivation: {1044 Node* barrierNode = m_graph.addNode(1045 SpecNone, StoreBarrierWithNullCheck, m_currentNode->origin,1046 Edge(node->child1().node(), UntypedUse));1047 1039 m_insertionSet.insert(m_indexInBlock, barrierNode); 1048 1040 break; -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r174224 r174226 1014 1014 if (!lexicalEnvironment) 1015 1015 return 0; 1016 if (!lexicalEnvironment->isTornOff())1017 return 0;1018 1016 return lexicalEnvironment->registers(); 1019 1017 } -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r174167 r174226 264 264 /* being threaded with each other. */\ 265 265 macro(CreateActivation, NodeResultJS) \ 266 macro(TearOffActivation, NodeMustGenerate) \267 266 \ 268 267 /* Nodes used for arguments. Similar to lexical environment support, only it makes even less */\ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r174167 r174226 657 657 case CheckBadCell: 658 658 case PutStructure: 659 case TearOffActivation:660 659 case TearOffArguments: 661 660 case CheckArgumentsNotCreated: -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r174167 r174226 218 218 case In: 219 219 case CreateActivation: 220 case TearOffActivation:221 220 case CreateArguments: 222 221 case PhantomArguments: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r174167 r174226 4171 4171 4172 4172 case CreateActivation: { 4173 JSValueOperand value(this, node->child1()); 4174 GPRTemporary result(this, Reuse, value, PayloadWord); 4175 4176 GPRReg valueTagGPR = value.tagGPR(); 4177 GPRReg valuePayloadGPR = value.payloadGPR(); 4173 GPRTemporary result(this); 4178 4174 GPRReg resultGPR = result.gpr(); 4179 4180 m_jit.move(valuePayloadGPR, resultGPR); 4181 4182 JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag)); 4183 4184 addSlowPathGenerator( 4185 slowPathCall( 4186 notCreated, this, operationCreateActivation, resultGPR, 4187 framePointerOffsetToGetActivationRegisters())); 4175 4176 flushRegisters(); 4177 callOperation(operationCreateActivation, resultGPR, framePointerOffsetToGetActivationRegisters()); 4188 4178 4189 4179 cellResult(resultGPR, node); … … 4240 4230 alreadyCreated.link(&m_jit); 4241 4231 cellResult(resultGPR, node); 4242 break;4243 }4244 4245 case TearOffActivation: {4246 JSValueOperand activationValue(this, node->child1());4247 GPRTemporary scratch(this);4248 4249 GPRReg activationValueTagGPR = activationValue.tagGPR();4250 GPRReg activationValuePayloadGPR = activationValue.payloadGPR();4251 GPRReg scratchGPR = scratch.gpr();4252 4253 JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, activationValueTagGPR, TrustedImm32(JSValue::EmptyValueTag));4254 4255 SymbolTable* symbolTable = m_jit.symbolTableFor(node->origin.semantic);4256 int registersOffset = JSLexicalEnvironment::registersOffset(symbolTable);4257 4258 int bytecodeCaptureStart = symbolTable->captureStart();4259 int machineCaptureStart = m_jit.graph().m_machineCaptureStart;4260 for (int i = symbolTable->captureCount(); i--;) {4261 m_jit.loadPtr(4262 JITCompiler::Address(4263 GPRInfo::callFrameRegister, (machineCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),4264 scratchGPR);4265 m_jit.storePtr(4266 scratchGPR, JITCompiler::Address(4267 activationValuePayloadGPR, registersOffset + (bytecodeCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));4268 m_jit.loadPtr(4269 JITCompiler::Address(4270 GPRInfo::callFrameRegister, (machineCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),4271 scratchGPR);4272 m_jit.storePtr(4273 scratchGPR, JITCompiler::Address(4274 activationValuePayloadGPR, registersOffset + (bytecodeCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));4275 }4276 m_jit.addPtr(TrustedImm32(registersOffset), activationValuePayloadGPR, scratchGPR);4277 m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValuePayloadGPR, JSLexicalEnvironment::offsetOfRegisters()));4278 4279 notCreated.link(&m_jit);4280 noResult(node);4281 4232 break; 4282 4233 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r174167 r174226 4237 4237 DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame); 4238 4238 4239 JSValueOperand value(this, node->child1()); 4240 GPRTemporary result(this, Reuse, value); 4241 4242 GPRReg valueGPR = value.gpr(); 4239 GPRTemporary result(this); 4243 4240 GPRReg resultGPR = result.gpr(); 4244 4245 m_jit.move(valueGPR, resultGPR); 4246 4247 JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR); 4248 4249 addSlowPathGenerator( 4250 slowPathCall( 4251 notCreated, this, operationCreateActivation, resultGPR, 4252 framePointerOffsetToGetActivationRegisters())); 4253 4241 4242 flushRegisters(); 4243 callOperation(operationCreateActivation, resultGPR, framePointerOffsetToGetActivationRegisters()); 4244 4254 4245 cellResult(resultGPR, node); 4255 4246 break; … … 4304 4295 alreadyCreated.link(&m_jit); 4305 4296 cellResult(resultGPR, node); 4306 break;4307 }4308 4309 case TearOffActivation: {4310 DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);4311 4312 JSValueOperand activationValue(this, node->child1());4313 GPRTemporary scratch(this);4314 GPRReg activationValueGPR = activationValue.gpr();4315 GPRReg scratchGPR = scratch.gpr();4316 4317 JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, activationValueGPR);4318 4319 SymbolTable* symbolTable = m_jit.symbolTableFor(node->origin.semantic);4320 int registersOffset = JSLexicalEnvironment::registersOffset(symbolTable);4321 4322 int bytecodeCaptureStart = symbolTable->captureStart();4323 int machineCaptureStart = m_jit.graph().m_machineCaptureStart;4324 for (int i = symbolTable->captureCount(); i--;) {4325 m_jit.load64(4326 JITCompiler::Address(4327 GPRInfo::callFrameRegister,4328 (machineCaptureStart - i) * sizeof(Register)),4329 scratchGPR);4330 m_jit.store64(4331 scratchGPR,4332 JITCompiler::Address(4333 activationValueGPR,4334 registersOffset + (bytecodeCaptureStart - i) * sizeof(Register)));4335 }4336 m_jit.addPtr(TrustedImm32(registersOffset), activationValueGPR, scratchGPR);4337 m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValueGPR, JSLexicalEnvironment::offsetOfRegisters()));4338 4339 notCreated.link(&m_jit);4340 noResult(node);4341 4297 break; 4342 4298 } -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r174165 r174226 370 370 if (graph.m_codeBlock->needsActivation()) { 371 371 // Need this because although we also don't support 372 // CreateActivation /TearOffActivation, we might not see those nodes in case of372 // CreateActivation, we might not see those nodes in case of 373 373 // OSR entry. 374 374 // FIXME: Support activations. -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r173600 r174226 440 440 CallFrame* callFrame = visitor->callFrame(); 441 441 CodeBlock* codeBlock = visitor->codeBlock(); 442 JSScope* scope = callFrame->scope();443 444 442 if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) { 445 443 ClearExceptionScope scope(&callFrame->vm()); … … 456 454 RELEASE_ASSERT(!visitor->isInlinedFrame()); 457 455 #endif 458 lexicalEnvironment = callFrame->uncheckedActivation();459 // Protect against the lexical environment not being created, or the variable still being460 // initialized to Undefined inside op_enter.461 if (lexicalEnvironment && lexicalEnvironment.isCell()) {462 JSLexicalEnvironment* activationObject = jsCast<JSLexicalEnvironment*>(lexicalEnvironment);463 // Protect against throwing exceptions after tear-off.464 if (!activationObject->isTornOff())465 activationObject->tearOff(*scope->vm());466 }467 456 } 468 457 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r173517 r174226 248 248 DEFINE_OP(op_lshift) 249 249 DEFINE_OP(op_mod) 250 DEFINE_OP(op_captured_mov)251 250 DEFINE_OP(op_mov) 252 251 DEFINE_OP(op_mul) … … 297 296 DEFINE_OP(op_switch_imm) 298 297 DEFINE_OP(op_switch_string) 299 DEFINE_OP(op_tear_off_lexical_environment)300 298 DEFINE_OP(op_tear_off_arguments) 301 299 DEFINE_OP(op_throw) … … 385 383 DEFINE_SLOWCASE_OP(op_to_this) 386 384 DEFINE_SLOWCASE_OP(op_create_this) 387 DEFINE_SLOWCASE_OP(op_captured_mov)388 385 DEFINE_SLOWCASE_OP(op_div) 389 386 DEFINE_SLOWCASE_OP(op_eq) -
trunk/Source/JavaScriptCore/jit/JIT.h
r174216 r174226 464 464 void emit_op_call_varargs(Instruction*); 465 465 void emit_op_construct_varargs(Instruction*); 466 void emit_op_captured_mov(Instruction*);467 466 void emit_op_catch(Instruction*); 468 467 void emit_op_construct(Instruction*); … … 544 543 void emit_op_switch_imm(Instruction*); 545 544 void emit_op_switch_string(Instruction*); 546 void emit_op_tear_off_lexical_environment(Instruction*);547 545 void emit_op_tear_off_arguments(Instruction*); 548 546 void emit_op_throw(Instruction*); … … 571 569 void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); 572 570 void emitSlow_op_construct_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&); 573 void emitSlow_op_captured_mov(Instruction*, Vector<SlowCaseEntry>::iterator&);574 571 void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&); 575 572 void emitSlow_op_to_this(Instruction*, Vector<SlowCaseEntry>::iterator&); … … 641 638 #endif 642 639 void emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet*); 643 void emitPutClosureVar(int scope, uintptr_t operand, int value );640 void emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet*); 644 641 645 642 void emitInitRegister(int dst); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r174216 r174226 64 64 } 65 65 66 void JIT::emit_op_captured_mov(Instruction* currentInstruction)67 {68 int dst = currentInstruction[1].u.operand;69 int src = currentInstruction[2].u.operand;70 71 emitGetVirtualRegister(src, regT0);72 emitNotifyWrite(regT0, regT1, currentInstruction[3].u.watchpointSet);73 emitPutVirtualRegister(dst);74 }75 66 76 67 void JIT::emit_op_end(Instruction* currentInstruction) … … 232 223 done.link(this); 233 224 emitPutVirtualRegister(dst); 234 }235 236 void JIT::emit_op_tear_off_lexical_environment(Instruction* currentInstruction)237 {238 int lexicalEnvironment = currentInstruction[1].u.operand;239 Jump activationNotCreated = branchTest64(Zero, addressFor(lexicalEnvironment));240 emitGetVirtualRegister(lexicalEnvironment, regT0);241 callOperation(operationTearOffActivation, regT0);242 activationNotCreated.link(this);243 225 } 244 226 … … 1099 1081 const JSValue* values = codeBlock()->constantBuffer(valuesIndex); 1100 1082 callOperation(operationNewArrayBufferWithProfile, dst, currentInstruction[4].u.arrayAllocationProfile, values, size); 1101 }1102 1103 void JIT::emitSlow_op_captured_mov(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)1104 {1105 VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet;1106 if (!set || set->state() == IsInvalidated)1107 return;1108 #if USE(JSVALUE32_64)1109 linkSlowCase(iter);1110 #endif1111 linkSlowCase(iter);1112 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_captured_mov);1113 slowPathCall.call();1114 1083 } 1115 1084 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r174216 r174226 154 154 } 155 155 156 void JIT::emit_op_captured_mov(Instruction* currentInstruction)157 {158 int dst = currentInstruction[1].u.operand;159 int src = currentInstruction[2].u.operand;160 161 emitLoad(src, regT1, regT0);162 emitNotifyWrite(regT1, regT0, regT2, currentInstruction[3].u.watchpointSet);163 emitStore(dst, regT1, regT0);164 }165 166 156 void JIT::emit_op_end(Instruction* currentInstruction) 167 157 { … … 349 339 done.link(this); 350 340 emitStoreBool(dst, regT0); 351 }352 353 void JIT::emit_op_tear_off_lexical_environment(Instruction* currentInstruction)354 {355 int lexicalEnvironment = currentInstruction[1].u.operand;356 Jump activationNotCreated = branch32(Equal, tagFor(lexicalEnvironment), TrustedImm32(JSValue::EmptyValueTag));357 emitLoadPayload(lexicalEnvironment, regT0);358 callOperation(operationTearOffActivation, regT0);359 activationNotCreated.link(this);360 341 } 361 342 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r174216 r174226 1590 1590 return JSValue::encode(result); 1591 1591 } 1592 1593 void JIT_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activationCell)1594 {1595 VM& vm = exec->vm();1596 NativeCallFrameTracer tracer(&vm, exec);1597 1598 ASSERT(exec->codeBlock()->needsActivation());1599 jsCast<JSLexicalEnvironment*>(activationCell)->tearOff(vm);1600 }1601 1592 1602 1593 void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell) … … 1772 1763 JSValue value = exec->r(pc[3].u.operand).jsValue(); 1773 1764 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand); 1774 1765 if (modeAndType.type() == LocalClosureVar) { 1766 JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope); 1767 environment->registerAt(pc[6].u.operand).set(vm, environment, value); 1768 if (VariableWatchpointSet* set = pc[5].u.watchpointSet) 1769 set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>"); 1770 return; 1771 } 1775 1772 if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) { 1776 1773 exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r174216 r174226 293 293 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL; 294 294 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL; 295 void JIT_OPERATION operationTearOffActivation(ExecState*, JSCell*) WTF_INTERNAL;296 295 void JIT_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL; 297 296 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r173490 r174226 622 622 addSlowCase(jump()); 623 623 break; 624 case LocalClosureVar: 625 RELEASE_ASSERT_NOT_REACHED(); 624 626 } 625 627 } … … 692 694 addSlowCase(jump()); 693 695 break; 696 case LocalClosureVar: 697 RELEASE_ASSERT_NOT_REACHED(); 694 698 } 695 699 emitPutVirtualRegister(dst); … … 739 743 } 740 744 741 void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value )745 void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet* set) 742 746 { 743 747 emitGetVirtualRegister(value, regT1); 744 748 emitGetVirtualRegister(scope, regT0); 745 749 loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0); 750 emitNotifyWrite(regT1, regT2, set); 746 751 storePtr(regT1, Address(regT0, operand * sizeof(Register))); 747 752 } … … 768 773 emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet); 769 774 break; 775 case LocalClosureVar: 770 776 case ClosureVar: 771 777 case ClosureVarWithVarInjectionChecks: 772 778 emitWriteBarrier(scope, value, ShouldFilterValue); 773 779 emitVarInjectionCheck(needsVarInjectionChecks(resolveType)); 774 emitPutClosureVar(scope, *operandSlot, value );780 emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet); 775 781 break; 776 782 case Dynamic: … … 784 790 ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type(); 785 791 unsigned linkCount = 0; 786 if (resolveType != GlobalVar && resolveType != ClosureVar )792 if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar) 787 793 linkCount++; 788 if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks )794 if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar) 789 795 && currentInstruction[5].u.watchpointSet->state() != IsInvalidated) 790 796 linkCount++; -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r173490 r174226 646 646 addSlowCase(jump()); 647 647 break; 648 case LocalClosureVar: 649 RELEASE_ASSERT_NOT_REACHED(); 648 650 } 649 651 } … … 717 719 addSlowCase(jump()); 718 720 break; 721 case LocalClosureVar: 722 RELEASE_ASSERT_NOT_REACHED(); 719 723 } 720 724 emitValueProfilingSite(); … … 770 774 } 771 775 772 void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value )776 void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet* set) 773 777 { 774 778 emitLoad(value, regT3, regT2); 775 779 emitLoad(scope, regT1, regT0); 780 emitNotifyWrite(regT3, regT2, regT4, set); 776 781 loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0); 777 782 store32(regT3, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); … … 800 805 emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet); 801 806 break; 807 case LocalClosureVar: 802 808 case ClosureVar: 803 809 case ClosureVarWithVarInjectionChecks: 804 810 emitWriteBarrier(scope, value, ShouldFilterValue); 805 811 emitVarInjectionCheck(needsVarInjectionChecks(resolveType)); 806 emitPutClosureVar(scope, *operandSlot, value );812 emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet); 807 813 break; 808 814 case Dynamic: … … 816 822 ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type(); 817 823 unsigned linkCount = 0; 818 if (resolveType != GlobalVar && resolveType != ClosureVar )824 if (resolveType != GlobalVar && resolveType != ClosureVar && resolveType != LocalClosureVar) 819 825 linkCount++; 820 if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks )826 if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar) 821 827 && currentInstruction[5].u.watchpointSet->state() != IsInvalidated) 822 828 linkCount += 2; -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r171660 r174226 144 144 ASSERT(FunctionCode == 2); 145 145 146 ASSERT(GlobalProperty == 0); 147 ASSERT(GlobalVar == 1); 148 ASSERT(ClosureVar == 2); 149 ASSERT(GlobalPropertyWithVarInjectionChecks == 3); 150 ASSERT(GlobalVarWithVarInjectionChecks == 4); 151 ASSERT(ClosureVarWithVarInjectionChecks == 5); 152 ASSERT(Dynamic == 6); 146 static_assert(GlobalProperty == 0, "LLInt assumes GlobalProperty ResultType is == 0"); 147 static_assert(GlobalVar == 1, "LLInt assumes GlobalVar ResultType is == 1"); 148 static_assert(ClosureVar == 2, "LLInt assumes ClosureVar ResultType is == 2"); 149 static_assert(LocalClosureVar == 3, "LLInt assumes LocalClosureVar ResultType is == 3"); 150 static_assert(GlobalPropertyWithVarInjectionChecks == 4, "LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 4"); 151 static_assert(GlobalVarWithVarInjectionChecks == 5, "LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 5"); 152 static_assert(ClosureVarWithVarInjectionChecks == 6, "LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 6"); 153 static_assert(Dynamic == 7, "LLInt assumes Dynamic ResultType is == 7"); 153 154 154 155 ASSERT(ResolveModeAndType::mask == 0xffff); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r174216 r174226 1246 1246 } 1247 1247 1248 LLINT_SLOW_PATH_DECL(slow_path_tear_off_lexical_environment)1249 {1250 LLINT_BEGIN();1251 ASSERT(exec->codeBlock()->needsActivation());1252 jsCast<JSLexicalEnvironment*>(LLINT_OP(1).jsValue())->tearOff(vm);1253 LLINT_END();1254 }1255 1256 1248 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments) 1257 1249 { … … 1412 1404 JSValue value = LLINT_OP_C(3).jsValue(); 1413 1405 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand); 1406 if (modeAndType.type() == LocalClosureVar) { 1407 JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope); 1408 environment->registerAt(pc[6].u.operand).set(vm, environment, value); 1409 if (VariableWatchpointSet* set = pc[5].u.watchpointSet) 1410 set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>"); 1411 LLINT_END(); 1412 } 1414 1413 1415 1414 if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r173517 r174226 103 103 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_varargs); 104 104 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_eval); 105 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_lexical_environment);106 105 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_arguments); 107 106 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_strcat); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r174216 r174226 184 184 const GlobalVar = 1 185 185 const ClosureVar = 2 186 const GlobalPropertyWithVarInjectionChecks = 3 187 const GlobalVarWithVarInjectionChecks = 4 188 const ClosureVarWithVarInjectionChecks = 5 189 const Dynamic = 6 186 const LocalClosureVar = 3 187 const GlobalPropertyWithVarInjectionChecks = 4 188 const GlobalVarWithVarInjectionChecks = 5 189 const ClosureVarWithVarInjectionChecks = 6 190 const Dynamic = 7 190 191 191 192 const ResolveModeMask = 0xffff -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r173886 r174226 825 825 end 826 826 827 _llint_op_captured_mov:828 traceExecution()829 loadi 8[PC], t1830 loadConstantOrVariable(t1, t2, t3)831 loadpFromInstruction(3, t0)832 btpz t0, .opCapturedMovReady833 notifyWrite(t0, t2, t3, t1, .opCapturedMovSlow)834 .opCapturedMovReady:835 loadi 4[PC], t0836 storei t2, TagOffset[cfr, t0, 8]837 storei t3, PayloadOffset[cfr, t0, 8]838 dispatch(4)839 840 .opCapturedMovSlow:841 callSlowPath(_slow_path_captured_mov)842 dispatch(4)843 844 845 827 _llint_op_not: 846 828 traceExecution() … … 1970 1952 slowPathForCall(slowPath) 1971 1953 end 1972 1973 1974 _llint_op_tear_off_lexical_environment:1975 traceExecution()1976 loadi 4[PC], t01977 bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationNotCreated1978 callSlowPath(_llint_slow_path_tear_off_lexical_environment)1979 .opTearOffActivationNotCreated:1980 dispatch(2)1981 1982 1954 1983 1955 _llint_op_tear_off_arguments: … … 2371 2343 andi ResolveModeMask, t0 2372 2344 2373 #pGlobalProperty: 2345 #pLocalClosureVar: 2346 bineq t0, LocalClosureVar, .pGlobalProperty 2347 writeBarrierOnOperands(1, 3) 2348 loadVariable(1, t2, t1, t0) 2349 putClosureVar() 2350 dispatch(7) 2351 2352 .pGlobalProperty: 2374 2353 bineq t0, GlobalProperty, .pGlobalVar 2375 2354 writeBarrierOnOperands(1, 3) -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r173706 r174226 708 708 end 709 709 710 _llint_op_captured_mov:711 traceExecution()712 loadisFromInstruction(2, t1)713 loadConstantOrVariable(t1, t2)714 loadpFromInstruction(3, t0)715 btpz t0, .opCapturedMovReady716 notifyWrite(t0, t2, t1, .opCapturedMovSlow)717 .opCapturedMovReady:718 loadisFromInstruction(1, t0)719 storeq t2, [cfr, t0, 8]720 dispatch(4)721 722 .opCapturedMovSlow:723 callSlowPath(_slow_path_captured_mov)724 dispatch(4)725 726 727 710 _llint_op_not: 728 711 traceExecution() … … 1827 1810 slowPathForCall(slowPath) 1828 1811 end 1829 1830 1831 _llint_op_tear_off_lexical_environment:1832 traceExecution()1833 loadisFromInstruction(1, t0)1834 btqz [cfr, t0, 8], .opTearOffActivationNotCreated1835 callSlowPath(_llint_slow_path_tear_off_lexical_environment)1836 .opTearOffActivationNotCreated:1837 dispatch(2)1838 1839 1812 1840 1813 _llint_op_tear_off_arguments: … … 2190 2163 end 2191 2164 2165 macro putLocalClosureVar() 2166 loadisFromInstruction(3, t1) 2167 loadConstantOrVariable(t1, t2) 2168 notifyWrite(t0, t2, t1, .pDynamic) 2169 loadp JSEnvironmentRecord::m_registers[t0], t0 2170 loadisFromInstruction(6, t1) 2171 storeq t2, [t0, t1, 8] 2172 end 2173 2192 2174 2193 2175 _llint_op_put_to_scope: … … 2196 2178 andi ResolveModeMask, t0 2197 2179 2198 #pGlobalProperty: 2180 #pLocalClosureVar: 2181 bineq t0, LocalClosureVar, .pGlobalProperty 2182 writeBarrierOnOperands(1, 3) 2183 loadVariable(1, t0) 2184 putLocalClosureVar() 2185 dispatch(7) 2186 2187 .pGlobalProperty: 2199 2188 bineq t0, GlobalProperty, .pGlobalVar 2200 2189 writeBarrierOnOperands(1, 3) -
trunk/Source/JavaScriptCore/runtime/Arguments.cpp
r173517 r174226 385 385 m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1; 386 386 387 // If we have a captured argument that logically aliases lexical environment storage, 388 // but we optimize away the lexicalEnvironment, the argument needs to tear off into 389 // our storage. The simplest way to do this is to revert it to Normal status. 390 if (m_slowArgumentData && !m_lexicalEnvironment) { 391 for (size_t i = 0; i < m_numArguments; ++i) { 392 if (m_slowArgumentData->slowArguments()[i].status != SlowArgument::Captured) 393 continue; 394 m_slowArgumentData->slowArguments()[i].status = SlowArgument::Normal; 395 m_slowArgumentData->slowArguments()[i].index = CallFrame::argumentOffset(i); 396 } 397 } 398 399 for (size_t i = 0; i < m_numArguments; ++i) 387 for (size_t i = 0; i < m_numArguments; ++i) { 388 if (m_slowArgumentData && m_slowArgumentData->slowArguments()[i].status == SlowArgument::Captured) 389 continue; 400 390 trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i)); 391 } 401 392 } 402 393 -
trunk/Source/JavaScriptCore/runtime/Arguments.h
r174036 r174226 271 271 272 272 int index = m_slowArgumentData->slowArguments()[argument].index; 273 if ( !m_lexicalEnvironment ||m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Captured)273 if (m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Captured) 274 274 return m_registers[index]; 275 275 276 return m_lexicalEnvironment->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset()); 276 JSLexicalEnvironment* lexicalEnvironment = m_lexicalEnvironment.get(); 277 if (!lexicalEnvironment) 278 lexicalEnvironment = CallFrame::create(reinterpret_cast<Register*>(m_registers))->lexicalEnvironment(); 279 return lexicalEnvironment->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset()); 277 280 } 278 281 -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r173517 r174226 263 263 } 264 264 265 SLOW_PATH_DECL(slow_path_captured_mov)266 {267 BEGIN();268 JSValue value = OP_C(2).jsValue();269 if (VariableWatchpointSet* set = pc[3].u.watchpointSet)270 set->notifyWrite(vm, value, "Executed op_captured_mov");271 RETURN(value);272 }273 274 265 SLOW_PATH_DECL(slow_path_new_captured_func) 275 266 { -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h
r173082 r174226 191 191 SLOW_PATH_HIDDEN_DECL(slow_path_get_callee); 192 192 SLOW_PATH_HIDDEN_DECL(slow_path_to_this); 193 SLOW_PATH_HIDDEN_DECL(slow_path_captured_mov);194 193 SLOW_PATH_HIDDEN_DECL(slow_path_new_captured_func); 195 194 SLOW_PATH_HIDDEN_DECL(slow_path_not); -
trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp
r173517 r174226 47 47 Base::visitChildren(thisObject, visitor); 48 48 49 // No need to mark our registers if they're still in the JSStack.50 if (!thisObject->isTornOff())51 return;52 53 49 for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i) 54 50 visitor.append(&thisObject->storage()[i]); … … 62 58 63 59 // Defend against the inspector asking for a var after it has been optimized out. 64 if ( isTornOff() &&!isValid(entry))60 if (!isValid(entry)) 65 61 return false; 66 62 … … 76 72 77 73 // Defend against the inspector asking for a var after it has been optimized out. 78 if ( isTornOff() &&!isValid(entry))74 if (!isValid(entry)) 79 75 return false; 80 76 … … 101 97 } 102 98 // Defend against the inspector asking for a var after it has been optimized out. 103 if ( isTornOff() &&!isValid(iter->value))99 if (!isValid(iter->value)) 104 100 return false; 105 101 if (VariableWatchpointSet* set = iter->value.watchpointSet()) … … 114 110 { 115 111 JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(object); 116 117 CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));118 if (shouldIncludeDontEnumProperties(mode) && !thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()))119 propertyNames.add(exec->propertyNames().arguments);120 112 121 113 { … … 160 152 JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(object); 161 153 162 if (propertyName == exec->propertyNames().arguments) {163 // Defend against the inspector asking for the arguments object after it has been optimized out.164 CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));165 if (!thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) {166 slot.setCustom(thisObject, DontEnum, argumentsGetter);167 return true;168 }169 }170 171 154 if (thisObject->symbolTableGet(propertyName, slot)) 172 155 return true; … … 219 202 JSLexicalEnvironment* lexicalEnvironment = jsCast<JSLexicalEnvironment*>(slotBase); 220 203 CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(lexicalEnvironment->m_registers)); 221 ASSERT(!lexicalEnvironment->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())); 222 if (lexicalEnvironment->isTornOff() || !(callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) 223 return JSValue::encode(jsUndefined()); 204 return JSValue::encode(jsUndefined()); 224 205 225 206 VirtualRegister argumentsRegister = callFrame->codeBlock()->argumentsRegister(); -
trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h
r173517 r174226 42 42 class JSLexicalEnvironment : public JSEnvironmentRecord { 43 43 private: 44 JSLexicalEnvironment(VM&, CallFrame*, Register*, SymbolTable*);44 JSLexicalEnvironment(VM&, CallFrame*, Register*, CodeBlock*); 45 45 46 46 public: … … 57 57 allocationSize(symbolTable) 58 58 ) 59 ) JSLexicalEnvironment(vm, callFrame, registers, symbolTable);59 ) JSLexicalEnvironment(vm, callFrame, registers, codeBlock); 60 60 lexicalEnvironment->finishCreation(vm); 61 61 return lexicalEnvironment; … … 78 78 static JSValue toThis(JSCell*, ExecState*, ECMAMode); 79 79 80 void tearOff(VM&);81 82 80 DECLARE_INFO; 83 81 … … 87 85 bool isValidIndex(int) const; 88 86 bool isValid(const SymbolTableEntry&) const; 89 bool isTornOff();90 87 int registersOffset(); 91 88 static int registersOffset(SymbolTable*); … … 112 109 extern int allTheThingsCount; 113 110 114 inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, CallFrame* callFrame, Register* registers, SymbolTable* symbolTable)111 inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, CallFrame* callFrame, Register* registers, CodeBlock* codeBlock) 115 112 : Base( 116 113 vm, … … 118 115 registers, 119 116 callFrame->scope(), 120 symbolTable)117 codeBlock->symbolTable()) 121 118 { 119 SymbolTable* symbolTable = codeBlock->symbolTable(); 122 120 WriteBarrier<Unknown>* storage = this->storage(); 123 121 size_t captureCount = symbolTable->captureCount(); 124 122 for (size_t i = 0; i < captureCount; ++i) 125 new (NotNull, &storage[i]) WriteBarrier<Unknown>; 123 new (NotNull, &storage[i]) WriteBarrier<Unknown>(UndefinedWriteBarrierTag); 124 m_registers = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>( 125 reinterpret_cast<char*>(this) + registersOffset(symbolTable)); 126 126 } 127 127 … … 142 142 { 143 143 return storageOffset() + ((symbolTable->captureCount() - symbolTable->captureStart() - 1) * sizeof(WriteBarrier<Unknown>)); 144 }145 146 inline void JSLexicalEnvironment::tearOff(VM& vm)147 {148 ASSERT(!isTornOff());149 150 WriteBarrierBase<Unknown>* dst = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(151 reinterpret_cast<char*>(this) + registersOffset(symbolTable()));152 WriteBarrierBase<Unknown>* src = m_registers;153 154 int captureEnd = symbolTable()->captureEnd();155 for (int i = symbolTable()->captureStart(); i > captureEnd; --i)156 dst[i].set(vm, this, src[i].get());157 158 m_registers = dst;159 ASSERT(isTornOff());160 }161 162 inline bool JSLexicalEnvironment::isTornOff()163 {164 return m_registers == reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(165 reinterpret_cast<char*>(this) + registersOffset(symbolTable()));166 144 } 167 145 -
trunk/Source/JavaScriptCore/runtime/JSScope.cpp
r173517 r174226 181 181 "GlobalVar", 182 182 "ClosureVar", 183 "LocalClosureVar", 183 184 "GlobalPropertyWithVarInjectionChecks", 184 185 "GlobalVarWithVarInjectionChecks", … … 186 187 "Dynamic" 187 188 }; 188 ASSERT(type < sizeof(names) / sizeof(names[0]));189 189 return names[type]; 190 190 } -
trunk/Source/JavaScriptCore/runtime/JSScope.h
r173706 r174226 44 44 GlobalVar, 45 45 ClosureVar, 46 LocalClosureVar, 46 47 47 48 // Ditto, but at least one intervening scope used non-strict eval, which … … 69 70 return GlobalVarWithVarInjectionChecks; 70 71 case ClosureVar: 72 case LocalClosureVar: 71 73 return ClosureVarWithVarInjectionChecks; 72 74 case GlobalPropertyWithVarInjectionChecks: … … 87 89 case GlobalVar: 88 90 case ClosureVar: 91 case LocalClosureVar: 89 92 return false; 90 93 case GlobalPropertyWithVarInjectionChecks: -
trunk/Source/JavaScriptCore/runtime/WriteBarrier.h
r169703 r174226 202 202 }; 203 203 204 enum UndefinedWriteBarrierTagType { UndefinedWriteBarrierTag }; 204 205 template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> { 205 206 WTF_MAKE_FAST_ALLOCATED; … … 209 210 this->setWithoutWriteBarrier(JSValue()); 210 211 } 212 WriteBarrier(UndefinedWriteBarrierTagType) 213 { 214 this->setWithoutWriteBarrier(jsUndefined()); 215 } 211 216 212 217 WriteBarrier(VM& vm, const JSCell* owner, JSValue value)
Note:
See TracChangeset
for help on using the changeset viewer.