Changeset 163223 in webkit
- Timestamp:
- Jan 31, 2014 5:24:39 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r163214 r163223 1 2014-01-31 Mark Lam <mark.lam@apple.com> 2 3 Avoid eagerly creating the JSActivation when the debugger is attached. 4 <https://webkit.org/b/127910> 5 6 Reviewed by Oliver Hunt. 7 8 Octane scores for this patch: 9 baseline w/o WebInspector: 11621 10 patched w/o WebInspector: 11801 11 baseline w/ WebInspector: 3295 12 patched w/ WebInspector: 7070 2.1x improvement 13 14 1. Because debugger can potentially create a closure from any call frame, 15 we need every function to allocate an activation register and check for 16 the need to tear off the activation (if needed) on return. 17 18 However, we do not need to eagerly create the activation object. 19 This patch implements the optimization to defer creation of the 20 activation object until we actually need it i.e. when: 21 22 1. We encounter a "eval", "with", or "catch" statement. 23 2. We've paused in the debugger, and called DebuggerCallFrame::scope(). 24 25 2. The UnlinkedCodeBlock provides a needsFullScopeChain flag that is used 26 to indicate whether the linked CodeBlock will need an activation 27 object or not. Under normal circumstances, needsFullScopeChain and 28 needsActivation are synonymous. However, with a debugger attached, we 29 want the CodeBlock to always allocate an activationRegister even if 30 it does not need a "full scope chain". 31 32 Hence, we apply the following definitions to the "flags": 33 34 1. UnlinkedCodeBlock::needsFullScopeChain() - this flag indicates that 35 the parser discovered JS artifacts (e.g. use of "eval", "with", etc.) 36 that requires an activation. 37 38 BytecodeGenerator's destinationForAssignResult() and leftHandSideNeedsCopy() 39 checks needsFullScopeChain(). 40 41 2. UnlinkedCodeBlock::hasActivationRegister() - this flag indicates that 42 an activation register was created for the UnlinkedCodeBlock either 43 because it needsFullScopeChain() or because the debugger is attached. 44 45 3. CodeBlock::needsActivation() reflects UnlinkedCodeBlock's 46 hasActivationRegister(). 47 48 3. Introduced BytecodeGenerator::emitPushFunctionNameScope() and 49 BytecodeGenerator::emitPushCatchScope() because the JSNameScope 50 pushed for a function name cannot be popped unlike the JSNameScope 51 pushed for a "catch". Hence, we have 2 functions to handle the 2 cases 52 differently. 53 54 4. Removed DebuggerCallFrame::evaluateWithCallFrame() and require that all 55 debugger evaluations go through the DebuggerCallFrame::evaluate(). This 56 ensures that debugger evaluations require a DebuggerCallFrame. 57 58 DebuggerCallFrame::evaluateWithCallFrame() was used previously because 59 we didn't want to instantiate a DebuggerCallFrame on every debug hook 60 callback. However, we now only call the debug hooks when needed, and 61 this no longer poses a performance problem. 62 63 In addition, when the debug hook does an eval to test a breakpoint 64 condition, it is incorrect to evaluate it without a DebuggerCallFrame 65 anyway. 66 67 5. Added some utility functions to the CallFrame to make it easier to work 68 with the activation register in the frame (if present). These utility 69 functions should only be called if the CodeBlock::needsActivation() is 70 true (which indicates the presence of the activation register). The 71 utlity functions are: 72 73 1. CallFrame::hasActivation() 74 - checks if the frame's activation object has been created. 75 76 2. CallFrame::activation() 77 - returns the frame's activation object. 78 79 3. CallFrame::uncheckedActivation() 80 - returns the JSValue in the frame's activation register. May be null. 81 82 4. CallFrame::setActivation() 83 - sets the frame's activation object. 84 85 * bytecode/CodeBlock.cpp: 86 (JSC::CodeBlock::dumpBytecode): 87 - added symbollic dumping of ResolveMode and ResolveType values for some 88 bytecodes. 89 (JSC::CodeBlock::CodeBlock): 90 * bytecode/CodeBlock.h: 91 (JSC::CodeBlock::activationRegister): 92 (JSC::CodeBlock::uncheckedActivationRegister): 93 (JSC::CodeBlock::needsActivation): 94 * bytecode/UnlinkedCodeBlock.h: 95 (JSC::UnlinkedCodeBlock::needsFullScopeChain): 96 (JSC::UnlinkedCodeBlock::hasActivationRegister): 97 * bytecompiler/BytecodeGenerator.cpp: 98 (JSC::BytecodeGenerator::BytecodeGenerator): 99 (JSC::BytecodeGenerator::resolveCallee): 100 (JSC::BytecodeGenerator::createActivationIfNecessary): 101 (JSC::BytecodeGenerator::emitCallEval): 102 (JSC::BytecodeGenerator::emitReturn): 103 (JSC::BytecodeGenerator::emitPushWithScope): 104 (JSC::BytecodeGenerator::emitPushFunctionNameScope): 105 (JSC::BytecodeGenerator::emitPushCatchScope): 106 * bytecompiler/BytecodeGenerator.h: 107 * bytecompiler/NodesCodegen.cpp: 108 (JSC::TryNode::emitBytecode): 109 * debugger/Debugger.cpp: 110 (JSC::Debugger::hasBreakpoint): 111 (JSC::Debugger::pauseIfNeeded): 112 * debugger/DebuggerCallFrame.cpp: 113 (JSC::DebuggerCallFrame::scope): 114 (JSC::DebuggerCallFrame::evaluate): 115 * debugger/DebuggerCallFrame.h: 116 * dfg/DFGByteCodeParser.cpp: 117 (JSC::DFG::ByteCodeParser::parseCodeBlock): 118 * dfg/DFGGraph.h: 119 - Removed an unused function DFGGraph::needsActivation(). 120 * interpreter/CallFrame.cpp: 121 (JSC::CallFrame::activation): 122 (JSC::CallFrame::setActivation): 123 * interpreter/CallFrame.h: 124 (JSC::ExecState::hasActivation): 125 (JSC::ExecState::registers): 126 * interpreter/CallFrameInlines.h: 127 (JSC::CallFrame::uncheckedActivation): 128 * interpreter/Interpreter.cpp: 129 (JSC::unwindCallFrame): 130 (JSC::Interpreter::unwind): 131 * jit/JITOperations.cpp: 132 * llint/LLIntSlowPaths.cpp: 133 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 134 * runtime/CommonSlowPaths.cpp: 135 (JSC::SLOW_PATH_DECL): 136 137 * runtime/JSScope.cpp: 138 * runtime/JSScope.h: 139 (JSC::resolveModeName): 140 (JSC::resolveTypeName): 141 - utility functions for decoding names of the ResolveMode and ResolveType. 142 These are used in CodeBlock::dumpBytecode(). 143 1 144 2014-01-31 Michael Saboff <msaboff@apple.com> 2 145 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r163195 r163223 533 533 unmodifiedArgumentsRegister(argumentsRegister()).offset()); 534 534 } 535 if (needs FullScopeChain() && codeType() == FunctionCode)535 if (needsActivation() && codeType() == FunctionCode) 536 536 out.printf("; activation in r%d", activationRegister().offset()); 537 537 out.printf("\n"); … … 1383 1383 int r0 = (++it)->u.operand; 1384 1384 int id0 = (++it)->u.operand; 1385 int resolveModeAndType = (++it)->u.operand;1386 ++it; // depth1385 ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand); 1386 int depth = (++it)->u.operand; 1387 1387 printLocationAndOp(out, exec, location, it, "resolve_scope"); 1388 out.printf("%s, %s, %d", registerName(r0).data(), idName(id0, identifier(id0)).data(), resolveModeAndType); 1388 out.printf("%s, %s, %u<%s|%s>, %d", registerName(r0).data(), idName(id0, identifier(id0)).data(), 1389 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()), 1390 depth); 1389 1391 ++it; 1390 1392 break; … … 1394 1396 int r1 = (++it)->u.operand; 1395 1397 int id0 = (++it)->u.operand; 1396 int resolveModeAndType = (++it)->u.operand;1398 ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand); 1397 1399 ++it; // Structure 1398 ++it; // Operand1400 int operand = (++it)->u.operand; // Operand 1399 1401 ++it; // Skip value profile. 1400 1402 printLocationAndOp(out, exec, location, it, "get_from_scope"); 1401 out.printf("%s, %s, %s, %d", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(), resolveModeAndType); 1403 out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d", 1404 registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(), 1405 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()), 1406 operand); 1402 1407 break; 1403 1408 } … … 1406 1411 int id0 = (++it)->u.operand; 1407 1412 int r1 = (++it)->u.operand; 1408 int resolveModeAndType = (++it)->u.operand;1413 ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand); 1409 1414 ++it; // Structure 1410 ++it; // Operand1415 int operand = (++it)->u.operand; // Operand 1411 1416 printLocationAndOp(out, exec, location, it, "put_to_scope"); 1412 out.printf("%s, %s, %s, %d", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(), resolveModeAndType); 1417 out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d", 1418 registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(), 1419 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()), 1420 operand); 1413 1421 break; 1414 1422 } … … 1543 1551 , m_activationRegister(unlinkedCodeBlock->activationRegister()) 1544 1552 , m_isStrictMode(unlinkedCodeBlock->isStrictMode()) 1545 , m_needsActivation(unlinkedCodeBlock-> needsFullScopeChain() && unlinkedCodeBlock->codeType() == FunctionCode)1553 , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode) 1546 1554 , m_source(sourceProvider) 1547 1555 , m_sourceOffset(sourceOffset) … … 1868 1876 if (Options::dumpGeneratedBytecodes()) 1869 1877 dumpBytecode(); 1870 1871 1878 1872 1879 m_heap->m_codeBlocks.add(this); -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r163195 r163223 306 306 VirtualRegister thisRegister() const { return m_thisRegister; } 307 307 308 bool needsFullScopeChain() const { return m_unlinkedCode->needsFullScopeChain(); }309 308 bool usesEval() const { return m_unlinkedCode->usesEval(); } 310 309 … … 333 332 VirtualRegister activationRegister() const 334 333 { 335 ASSERT( needsFullScopeChain());334 ASSERT(m_activationRegister.isValid()); 336 335 return m_activationRegister; 337 336 } … … 339 338 VirtualRegister uncheckedActivationRegister() 340 339 { 341 if (!needsFullScopeChain()) 342 return VirtualRegister(); 343 return activationRegister(); 340 return m_activationRegister; 344 341 } 345 342 … … 348 345 bool needsActivation() const 349 346 { 347 ASSERT(m_activationRegister.isValid() == m_needsActivation); 350 348 return m_needsActivation; 351 349 } -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r163195 r163223 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 270 270 271 271 bool needsFullScopeChain() const { return m_needsFullScopeChain; } 272 void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }273 272 274 273 void addExpressionInfo(unsigned instructionOffset, int divot, … … 426 425 VirtualRegister thisRegister() const { return m_thisRegister; } 427 426 VirtualRegister activationRegister() const { return m_activationRegister; } 428 427 bool hasActivationRegister() const { return m_activationRegister.isValid(); } 429 428 430 429 void addPropertyAccessInstruction(unsigned propertyAccessInstruction) -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r163210 r163223 158 158 , m_codeBlock(vm, codeBlock) 159 159 , m_thisRegister(CallFrame::thisArgumentOffset()) 160 , m_activationRegister(0) 160 161 , m_emptyValueRegister(0) 161 162 , m_globalObjectRegister(0) … … 165 166 , m_nextConstantOffset(0) 166 167 , m_globalConstantIndex(0) 167 , m_hasCreatedActivation(true)168 168 , m_firstLazyFunction(0) 169 169 , m_lastLazyFunction(0) … … 178 178 , m_isBuiltinFunction(false) 179 179 { 180 if (m_shouldEmitDebugHooks)181 m_codeBlock->setNeedsFullScopeChain(true);182 183 180 m_codeBlock->setNumParameters(1); // Allocate space for "this" 184 181 … … 213 210 , m_nextConstantOffset(0) 214 211 , m_globalConstantIndex(0) 215 , m_hasCreatedActivation(false)216 212 , m_firstLazyFunction(0) 217 213 , m_lastLazyFunction(0) … … 231 227 } 232 228 233 if (m_shouldEmitDebugHooks)234 m_codeBlock->setNeedsFullScopeChain(true);235 236 229 m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode()); 237 230 Vector<Identifier> boundParameterProperties; … … 247 240 248 241 emitOpcode(op_enter); 249 if (m_codeBlock->needsFullScopeChain() ) {242 if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) { 250 243 m_activationRegister = addVar(); 251 244 emitInitLazyRegister(m_activationRegister); … … 316 309 // Captured variables and functions go first so that activations don't have 317 310 // to step over the non-captured locals to mark them. 318 m_hasCreatedActivation = false;319 311 if (functionBody->hasCapturedVariables()) { 320 312 for (size_t i = 0; i < functionStack.size(); ++i) { … … 322 314 const Identifier& ident = function->ident(); 323 315 if (functionBody->captures(ident)) { 324 if (!m_hasCreatedActivation) {325 m_hasCreatedActivation = true;326 emitOpcode(op_create_activation);327 instructions().append(m_activationRegister->index());328 }329 316 m_functions.add(ident.impl()); 330 317 emitNewFunction(addVar(ident, IsVariable, IsWatchable), IsCaptured, function); … … 337 324 } 338 325 } 326 327 m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset()); 328 339 329 bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks; 340 if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {341 m_hasCreatedActivation = true;342 emitOpcode(op_create_activation);343 instructions().append(m_activationRegister->index());344 }345 346 m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset());347 348 330 m_firstLazyFunction = codeBlock->m_numVars; 349 331 for (size_t i = 0; i < functionStack.size(); ++i) { … … 428 410 , m_codeBlock(vm, codeBlock) 429 411 , m_thisRegister(CallFrame::thisArgumentOffset()) 412 , m_activationRegister(0) 430 413 , m_emptyValueRegister(0) 431 414 , m_globalObjectRegister(0) … … 435 418 , m_nextConstantOffset(0) 436 419 , m_globalConstantIndex(0) 437 , m_hasCreatedActivation(true)438 420 , m_firstLazyFunction(0) 439 421 , m_lastLazyFunction(0) … … 448 430 , m_isBuiltinFunction(false) 449 431 { 450 m_codeBlock->setNeedsFullScopeChain(true);451 452 432 m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode()); 453 433 m_codeBlock->setNumParameters(1); … … 492 472 // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. 493 473 if (m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) 494 emitPush NameScope(functionBodyNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);474 emitPushFunctionNameScope(functionBodyNode->ident(), &m_calleeRegister, ReadOnly | DontDelete); 495 475 496 476 if (!functionBodyNode->captures(functionBodyNode->ident())) … … 1643 1623 void BytecodeGenerator::createActivationIfNecessary() 1644 1624 { 1645 if (m_hasCreatedActivation) 1646 return; 1647 if (!m_codeBlock->needsFullScopeChain()) 1625 if (!m_activationRegister) 1648 1626 return; 1649 1627 emitOpcode(op_create_activation); … … 1653 1631 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) 1654 1632 { 1633 createActivationIfNecessary(); 1655 1634 return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd); 1656 1635 } … … 1825 1804 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src) 1826 1805 { 1827 if (m_ codeBlock->needsFullScopeChain()) {1806 if (m_activationRegister) { 1828 1807 emitOpcode(op_tear_off_activation); 1829 1808 instructions().append(m_activationRegister->index()); … … 1933 1912 m_localScopeDepth++; 1934 1913 1914 createActivationIfNecessary(); 1935 1915 return emitUnaryNoDstOp(op_push_with_scope, scope); 1936 1916 } … … 2275 2255 } 2276 2256 2277 void BytecodeGenerator::emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes) 2278 { 2257 void BytecodeGenerator::emitPushFunctionNameScope(const Identifier& property, RegisterID* value, unsigned attributes) 2258 { 2259 emitOpcode(op_push_name_scope); 2260 instructions().append(addConstant(property)); 2261 instructions().append(value->index()); 2262 instructions().append(attributes); 2263 } 2264 2265 void BytecodeGenerator::emitPushCatchScope(const Identifier& property, RegisterID* value, unsigned attributes) 2266 { 2267 createActivationIfNecessary(); 2268 2279 2269 ControlFlowContext context; 2280 2270 context.isFinallyBlock = false; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r163195 r163223 1 1 /* 2 * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 4 4 * Copyright (C) 2012 Igalia, S.L. … … 426 426 void emitThrowReferenceError(const String& message); 427 427 428 void emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes); 428 void emitPushFunctionNameScope(const Identifier& property, RegisterID* value, unsigned attributes); 429 void emitPushCatchScope(const Identifier& property, RegisterID* value, unsigned attributes); 429 430 430 431 RegisterID* emitPushWithScope(RegisterID* scope); … … 656 657 int m_globalVarStorageOffset; 657 658 658 bool m_hasCreatedActivation;659 659 int m_firstLazyFunction; 660 660 int m_lastLazyFunction; -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r163195 r163223 2217 2217 } 2218 2218 2219 generator.emitPush NameScope(m_exceptionIdent, exceptionRegister.get(), DontDelete);2219 generator.emitPushCatchScope(m_exceptionIdent, exceptionRegister.get(), DontDelete); 2220 2220 generator.emitNode(dst, m_catchBlock); 2221 2221 generator.emitPopScope(); -
trunk/Source/JavaScriptCore/debugger/Debugger.cpp
r162970 r163223 454 454 455 455 JSValue exception; 456 JSValue result = DebuggerCallFrame::evaluateWithCallFrame(m_currentCallFrame, breakpoints[i].condition, exception); 456 DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame(); 457 JSValue result = debuggerCallFrame->evaluate(breakpoints[i].condition, exception); 457 458 458 459 // We can lose the debugger while executing JavaScript. … … 622 623 pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); 623 624 625 DebuggerCallFrameScope debuggerCallFrameScope(*this); 626 624 627 intptr_t sourceID = DebuggerCallFrame::sourceIDForCallFrame(m_currentCallFrame); 625 628 TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame); … … 628 631 if (!pauseNow) 629 632 return; 630 631 DebuggerCallFrameScope debuggerCallFrameScope(*this);632 633 633 634 // Make sure we are not going to pause again on breakpoint actions by -
trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
r163027 r163223 1 1 /* 2 * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include "DebuggerCallFrame.h" 31 31 32 #include " JSFunction.h"32 #include "CallFrameInlines.h" 33 33 #include "CodeBlock.h" 34 34 #include "Interpreter.h" 35 #include "JSActivation.h" 36 #include "JSFunction.h" 35 37 #include "Operations.h" 36 38 #include "Parser.h" … … 111 113 if (!isValid()) 112 114 return 0; 115 116 CodeBlock* codeBlock = m_callFrame->codeBlock(); 117 if (codeBlock && codeBlock->needsActivation() && !m_callFrame->hasActivation()) { 118 JSActivation* activation = JSActivation::create(*codeBlock->vm(), m_callFrame, codeBlock); 119 m_callFrame->setActivation(activation); 120 m_callFrame->setScope(activation); 121 } 122 113 123 return m_callFrame->scope(); 114 124 } … … 133 143 134 144 // Evaluate some JavaScript code in the scope of this frame. 135 JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception) const 136 { 137 ASSERT(isValid()); 138 return evaluateWithCallFrame(m_callFrame, script, exception); 139 } 140 141 JSValue DebuggerCallFrame::evaluateWithCallFrame(CallFrame* callFrame, const String& script, JSValue& exception) 142 { 145 JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception) 146 { 147 ASSERT(isValid()); 148 CallFrame* callFrame = m_callFrame; 143 149 if (!callFrame) 144 150 return jsNull(); … … 158 164 159 165 JSValue thisValue = thisValueForCallFrame(callFrame); 160 JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, callFrame->scope());166 JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()); 161 167 if (vm.exception()) { 162 168 exception = vm.exception(); -
trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
r162970 r163223 1 1 /* 2 * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 63 63 JS_EXPORT_PRIVATE Type type() const; 64 64 JS_EXPORT_PRIVATE JSValue thisValue() const; 65 JS _EXPORT_PRIVATE JSValue evaluate(const String&, JSValue& exception) const;65 JSValue evaluate(const String&, JSValue& exception); 66 66 67 67 bool isValid() const { return !!m_callFrame; } … … 71 71 // made private soon. Other clients should not use these. 72 72 73 JS_EXPORT_PRIVATE static JSValue evaluateWithCallFrame(CallFrame*, const String& script, JSValue& exception);74 73 JS_EXPORT_PRIVATE static TextPosition positionForCallFrame(CallFrame*); 75 74 JS_EXPORT_PRIVATE static SourceID sourceIDForCallFrame(CallFrame*); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r163069 r163223 3621 3621 dataLog( 3622 3622 ": captureCount = ", codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0, 3623 ", needsFullScopeChain = ", codeBlock->needsFullScopeChain(), 3624 ", needsActivation = ", codeBlock->ownerExecutable()->needsActivation(), 3623 ", needsActivation = ", codeBlock->needsActivation(), 3625 3624 ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n"); 3626 3625 codeBlock->baselineVersion()->dumpBytecode(); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r163027 r163223 1 1 /* 2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 570 570 571 571 return MethodOfGettingAValueProfile(valueProfileFor(node)); 572 }573 574 bool needsActivation() const575 {576 return m_codeBlock->needsFullScopeChain() && m_codeBlock->codeType() != GlobalCode;577 572 } 578 573 -
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r163027 r163223 1 1 /* 2 * Copyright (C) 2008, 2013 Apple Inc. All Rights Reserved.2 * Copyright (C) 2008, 2013, 2014 Apple Inc. All Rights Reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include "CodeBlock.h" 31 31 #include "Interpreter.h" 32 #include "JSActivation.h" 32 33 #include "Operations.h" 33 34 #include "VMEntryScope.h" … … 135 136 } 136 137 138 JSActivation* CallFrame::activation() const 139 { 140 CodeBlock* codeBlock = this->codeBlock(); 141 RELEASE_ASSERT(codeBlock->needsActivation()); 142 VirtualRegister activationRegister = codeBlock->activationRegister(); 143 return registers()[activationRegister.offset()].Register::activation(); 144 } 145 146 void CallFrame::setActivation(JSActivation* activation) 147 { 148 CodeBlock* codeBlock = this->codeBlock(); 149 RELEASE_ASSERT(codeBlock->needsActivation()); 150 VirtualRegister activationRegister = codeBlock->activationRegister(); 151 registers()[activationRegister.offset()] = activation; 152 } 153 137 154 } // namespace JSC -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r163027 r163223 2 2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 3 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 4 * Copyright (C) 2003, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.4 * Copyright (C) 2003, 2007, 2008, 2011, 2013, 2014 Apple Inc. All rights reserved. 5 5 * 6 6 * This library is free software; you can redistribute it and/or … … 50 50 return this[JSStack::ScopeChain].Register::scope(); 51 51 } 52 53 bool hasActivation() const { return !!uncheckedActivation(); } 54 JSActivation* activation() const; 55 inline JSValue uncheckedActivation() const; 52 56 53 57 // Global object in which execution began. … … 109 113 static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); } 110 114 Register* registers() { return this; } 115 const Register* registers() const { return this; } 111 116 112 117 CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; } … … 202 207 void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; } 203 208 void setScope(JSScope* scope) { static_cast<Register*>(this)[JSStack::ScopeChain] = scope; } 209 void setActivation(JSActivation*); 204 210 205 211 ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, JSScope* scope, -
trunk/Source/JavaScriptCore/interpreter/CallFrameInlines.h
r156229 r163223 28 28 29 29 #include "CallFrame.h" 30 #include "CodeBlock.h" 30 31 31 32 namespace JSC { … … 139 140 } 140 141 142 inline JSValue CallFrame::uncheckedActivation() const 143 { 144 CodeBlock* codeBlock = this->codeBlock(); 145 RELEASE_ASSERT(codeBlock->needsActivation()); 146 VirtualRegister activationRegister = codeBlock->activationRegister(); 147 return registers()[activationRegister.offset()].jsValue(); 148 } 149 141 150 } // namespace JSC 142 151 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r163195 r163223 33 33 #include "Arguments.h" 34 34 #include "BatchedTransitionOptimizer.h" 35 #include "CallFrame.h"36 35 #include "CallFrameClosure.h" 37 36 #include "CallFrameInlines.h" … … 429 428 RELEASE_ASSERT(!visitor->isInlinedFrame()); 430 429 #endif 431 activation = callFrame->unchecked R(codeBlock->activationRegister().offset()).jsValue();430 activation = callFrame->uncheckedActivation(); 432 431 if (activation) 433 432 jsCast<JSActivation*>(activation)->tearOff(*scope->vm()); … … 713 712 // Unwind the scope chain within the exception handler's call frame. 714 713 int targetScopeDepth = handler->scopeDepth; 715 if (codeBlock->needsActivation() && callFrame-> uncheckedR(codeBlock->activationRegister().offset()).jsValue())714 if (codeBlock->needsActivation() && callFrame->hasActivation()) 716 715 ++targetScopeDepth; 717 716 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r163195 r163223 616 616 { 617 617 ASSERT(exec->codeBlock()->codeType() != FunctionCode 618 || !exec->codeBlock()->needs FullScopeChain()619 || exec-> uncheckedR(exec->codeBlock()->activationRegister().offset()).jsValue());618 || !exec->codeBlock()->needsActivation() 619 || exec->hasActivation()); 620 620 621 621 execCallee->setScope(exec->scope()); … … 1521 1521 NativeCallFrameTracer tracer(&vm, exec); 1522 1522 1523 ASSERT(exec->codeBlock()->needs FullScopeChain());1523 ASSERT(exec->codeBlock()->needsActivation()); 1524 1524 jsCast<JSActivation*>(activationCell)->tearOff(vm); 1525 1525 } -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r163195 r163223 983 983 LLINT_BEGIN(); 984 984 CodeBlock* codeBlock = exec->codeBlock(); 985 ASSERT(codeBlock->codeType() != FunctionCode 986 || !codeBlock->needsFullScopeChain() 987 || exec->uncheckedR(codeBlock->activationRegister().offset()).jsValue()); 985 ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation()); 988 986 #if LLINT_SLOW_PATH_TRACING 989 987 dataLogF("Creating function!\n"); … … 1211 1209 { 1212 1210 LLINT_BEGIN(); 1213 ASSERT(exec->codeBlock()->needs FullScopeChain());1211 ASSERT(exec->codeBlock()->needsActivation()); 1214 1212 jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm); 1215 1213 LLINT_END(); -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r163195 r163223 271 271 BEGIN(); 272 272 CodeBlock* codeBlock = exec->codeBlock(); 273 ASSERT( 274 codeBlock->codeType() != FunctionCode 275 || !codeBlock->needsFullScopeChain() 276 || exec->uncheckedR(codeBlock->activationRegister().offset()).jsValue()); 273 ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation()); 277 274 JSValue value = JSFunction::create(vm, codeBlock->functionDecl(pc[2].u.operand), exec->scope()); 278 275 if (VariableWatchpointSet* set = pc[3].u.watchpointSet) -
trunk/Source/JavaScriptCore/runtime/JSScope.cpp
r160109 r163223 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 158 158 } 159 159 160 const char* resolveModeName(ResolveMode mode) 161 { 162 static const char* const names[] = { 163 "ThrowIfNotFound", 164 "DoNotThrowIfNotFound" 165 }; 166 return names[mode]; 167 } 168 169 const char* resolveTypeName(ResolveType type) 170 { 171 static const char* const names[] = { 172 "GlobalProperty", 173 "GlobalVar", 174 "ClosureVar", 175 "GlobalPropertyWithVarInjectionChecks", 176 "GlobalVarWithVarInjectionChecks", 177 "ClosureVarWithVarInjectionChecks", 178 "Dynamic" 179 }; 180 ASSERT(type < sizeof(names) / sizeof(names[0])); 181 return names[type]; 182 } 183 160 184 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSScope.h
r159834 r163223 1 1 /* 2 * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 55 55 }; 56 56 57 const char* resolveModeName(ResolveMode mode); 58 const char* resolveTypeName(ResolveType type); 59 57 60 inline ResolveType makeType(ResolveType type, bool needsVarInjectionChecks) 58 61 {
Note: See TracChangeset
for help on using the changeset viewer.