Changeset 95916 in webkit
- Timestamp:
- Sep 24, 2011 3:39:16 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r95914 r95916 1 2011-09-24 Filip Pizlo <fpizlo@apple.com> 2 3 The DFG should not attempt to guess types in the absence of value 4 profiles 5 https://bugs.webkit.org/show_bug.cgi?id=68677 6 7 Reviewed by Oliver Hunt. 8 9 This adds the ForceOSRExit node, which is ignored by the propagator 10 and virtual register allocator (and hence ensuring that liveness analysis 11 works correctly), but forces terminateSpeculativeExecution() in the 12 back-end. This appears to be a slight speed-up on benchmark averages, 13 with ~5% swings on individual benchmarks, in both directions. But it's 14 never a regression on any average, and appears to be a ~1% progression 15 in the SunSpider average. 16 17 This also adds a bit better debugging support in the old JIT and in DFG, 18 as this was necessary to debug the much more frequent OSR transitions 19 that occur with this change. 20 21 * dfg/DFGByteCodeParser.cpp: 22 (JSC::DFG::ByteCodeParser::addCall): 23 (JSC::DFG::ByteCodeParser::getStrongPrediction): 24 (JSC::DFG::ByteCodeParser::parseBlock): 25 * dfg/DFGJITCompiler.cpp: 26 (JSC::DFG::JITCompiler::exitSpeculativeWithOSR): 27 * dfg/DFGNode.h: 28 * dfg/DFGPropagator.cpp: 29 (JSC::DFG::Propagator::propagateNodePredictions): 30 * dfg/DFGSpeculativeJIT.cpp: 31 (JSC::DFG::SpeculativeJIT::compile): 32 * jit/JIT.cpp: 33 (JSC::JIT::privateCompileMainPass): 34 (JSC::JIT::privateCompileSlowCases): 35 (JSC::JIT::privateCompile): 36 * jit/JIT.h: 37 1 38 2011-09-24 Geoffrey Garen <ggaren@apple.com> 2 39 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r95902 r95916 433 433 NodeIndex addCall(Interpreter* interpreter, Instruction* currentInstruction, NodeType op) 434 434 { 435 Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call); 436 437 PredictedType prediction = PredictNone; 438 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) 439 prediction = getStrongPrediction(m_graph.size(), m_currentIndex + OPCODE_LENGTH(op_call)); 440 435 441 addVarArgChild(get(currentInstruction[1].u.operand)); 436 442 int argCount = currentInstruction[2].u.operand; … … 439 445 for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++) 440 446 addVarArgChild(get(argIdx)); 441 NodeIndex call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(PredictNone)); 442 Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call); 443 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) { 447 NodeIndex call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction)); 448 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) 444 449 set(putInstruction[1].u.operand, call); 445 stronglyPredict(call, m_currentIndex + OPCODE_LENGTH(op_call));446 }447 450 if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots) 448 451 m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount; … … 488 491 { 489 492 UNUSED_PARAM(nodeIndex); 490 UNUSED_PARAM(bytecodeIndex);491 493 492 494 ValueProfile* profile = m_profiledBlock->valueProfileForBytecodeOffset(bytecodeIndex); … … 496 498 printf("Dynamic [@%u, bc#%u] prediction: %s\n", nodeIndex, bytecodeIndex, predictionToString(prediction)); 497 499 #endif 500 501 if (prediction == PredictNone) { 502 // We have no information about what values this node generates. Give up 503 // on executing this code, since we're likely to do more damage than good. 504 addToGraph(ForceOSRExit); 505 } 506 498 507 return prediction; 499 508 } 500 509 501 void stronglyPredict(NodeIndex nodeIndex, unsigned bytecodeIndex) 502 { 503 m_graph[nodeIndex].predict(getStrongPrediction(nodeIndex, bytecodeIndex) & ~PredictionTagMask, StrongPrediction); 504 } 505 506 void stronglyPredict(NodeIndex nodeIndex) 507 { 508 stronglyPredict(nodeIndex, m_currentIndex); 509 } 510 510 PredictedType getStrongPrediction() 511 { 512 return getStrongPrediction(m_graph.size(), m_currentIndex); 513 } 514 511 515 NodeIndex makeSafe(NodeIndex nodeIndex) 512 516 { … … 1059 1063 1060 1064 case op_get_by_val: { 1065 PredictedType prediction = getStrongPrediction(); 1066 1061 1067 NodeIndex base = get(currentInstruction[2].u.operand); 1062 1068 NodeIndex property = get(currentInstruction[3].u.operand); … … 1064 1070 weaklyPredictInt32(property); 1065 1071 1066 NodeIndex getByVal = addToGraph(GetByVal, OpInfo(0), OpInfo( PredictNone), base, property);1072 NodeIndex getByVal = addToGraph(GetByVal, OpInfo(0), OpInfo(prediction), base, property); 1067 1073 set(currentInstruction[1].u.operand, getByVal); 1068 stronglyPredict(getByVal);1069 1074 1070 1075 NEXT_OPCODE(op_get_by_val); … … 1085 1090 case op_method_check: { 1086 1091 Instruction* getInstruction = currentInstruction + OPCODE_LENGTH(op_method_check); 1092 1093 PredictedType prediction = getStrongPrediction(); 1087 1094 1088 1095 ASSERT(interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id); … … 1110 1117 m_graph.m_methodCheckData.append(methodCheckData); 1111 1118 } else { 1112 NodeIndex getMethod = addToGraph(GetMethod, OpInfo(identifier), OpInfo( PredictNone), base);1119 NodeIndex getMethod = addToGraph(GetMethod, OpInfo(identifier), OpInfo(prediction), base); 1113 1120 set(getInstruction[1].u.operand, getMethod); 1114 stronglyPredict(getMethod);1115 1121 } 1116 1122 … … 1119 1125 } 1120 1126 case op_get_scoped_var: { 1127 PredictedType prediction = getStrongPrediction(); 1121 1128 int dst = currentInstruction[1].u.operand; 1122 1129 int slot = currentInstruction[2].u.operand; 1123 1130 int depth = currentInstruction[3].u.operand; 1124 1131 NodeIndex getScopeChain = addToGraph(GetScopeChain, OpInfo(depth)); 1125 NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo( PredictNone), getScopeChain);1132 NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo(prediction), getScopeChain); 1126 1133 set(dst, getScopedVar); 1127 stronglyPredict(getScopedVar);1128 1134 NEXT_OPCODE(op_get_scoped_var); 1129 1135 } … … 1137 1143 } 1138 1144 case op_get_by_id: { 1145 PredictedType prediction = getStrongPrediction(); 1146 1139 1147 NodeIndex base = get(currentInstruction[2].u.operand); 1140 1148 unsigned identifierNumber = currentInstruction[3].u.operand; … … 1149 1157 1150 1158 if (offset != notFound) { 1151 getById = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo( PredictNone), addToGraph(CheckStructure, OpInfo(structure), base));1159 getById = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), addToGraph(CheckStructure, OpInfo(structure), base)); 1152 1160 1153 1161 StorageAccessData storageAccessData; … … 1159 1167 1160 1168 if (getById == NoNode) 1161 getById = addToGraph(GetById, OpInfo(identifierNumber), OpInfo( PredictNone), base);1169 getById = addToGraph(GetById, OpInfo(identifierNumber), OpInfo(prediction), base); 1162 1170 1163 1171 set(currentInstruction[1].u.operand, getById); 1164 stronglyPredict(getById);1165 1172 1166 1173 NEXT_OPCODE(op_get_by_id); … … 1182 1189 1183 1190 case op_get_global_var: { 1191 PredictedType prediction = getStrongPrediction(); 1192 1184 1193 NodeIndex getGlobalVar = addToGraph(GetGlobalVar, OpInfo(currentInstruction[2].u.operand)); 1185 1194 set(currentInstruction[1].u.operand, getGlobalVar); 1186 m_graph.predictGlobalVar(currentInstruction[2].u.operand, getStrongPrediction(getGlobalVar, m_currentIndex)& ~PredictionTagMask, StrongPrediction);1195 m_graph.predictGlobalVar(currentInstruction[2].u.operand, prediction & ~PredictionTagMask, StrongPrediction); 1187 1196 NEXT_OPCODE(op_get_global_var); 1188 1197 } … … 1416 1425 1417 1426 case op_resolve: { 1427 PredictedType prediction = getStrongPrediction(); 1428 1418 1429 unsigned identifier = currentInstruction[2].u.operand; 1419 1430 1420 NodeIndex resolve = addToGraph(Resolve, OpInfo(identifier), OpInfo( PredictNone));1431 NodeIndex resolve = addToGraph(Resolve, OpInfo(identifier), OpInfo(prediction)); 1421 1432 set(currentInstruction[1].u.operand, resolve); 1422 stronglyPredict(resolve);1423 1433 1424 1434 NEXT_OPCODE(op_resolve); … … 1426 1436 1427 1437 case op_resolve_base: { 1438 PredictedType prediction = getStrongPrediction(); 1439 1428 1440 unsigned identifier = currentInstruction[2].u.operand; 1429 1441 1430 NodeIndex resolve = addToGraph(currentInstruction[3].u.operand ? ResolveBaseStrictPut : ResolveBase, OpInfo(identifier), OpInfo( PredictNone));1442 NodeIndex resolve = addToGraph(currentInstruction[3].u.operand ? ResolveBaseStrictPut : ResolveBase, OpInfo(identifier), OpInfo(prediction)); 1431 1443 set(currentInstruction[1].u.operand, resolve); 1432 stronglyPredict(resolve);1433 1444 1434 1445 NEXT_OPCODE(op_resolve_base); … … 1436 1447 1437 1448 case op_resolve_global: { 1438 NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(PredictNone)); 1449 PredictedType prediction = getStrongPrediction(); 1450 1451 NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction)); 1439 1452 m_graph.m_resolveGlobalData.append(ResolveGlobalData()); 1440 1453 ResolveGlobalData& data = m_graph.m_resolveGlobalData.last(); … … 1442 1455 data.resolveInfoIndex = m_globalResolveNumber++; 1443 1456 set(currentInstruction[1].u.operand, resolve); 1444 stronglyPredict(resolve);1445 1457 1446 1458 NEXT_OPCODE(op_resolve_global); -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r95910 r95916 110 110 exit.dump(stderr); 111 111 #endif 112 #if ENABLE(DFG_JIT_BREAK_ON_SPECULATION_FAILURE)113 breakpoint();114 #endif115 116 112 #if ENABLE(DFG_VERBOSE_SPECULATION_FAILURE) 117 113 SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo; … … 120 116 121 117 debugCall(debugOperationPrintSpeculationFailure, debugInfo); 118 #endif 119 120 #if ENABLE(DFG_JIT_BREAK_ON_SPECULATION_FAILURE) 121 breakpoint(); 122 122 #endif 123 123 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r95902 r95916 306 306 macro(Return, NodeMustGenerate | NodeIsTerminal) \ 307 307 macro(Throw, NodeMustGenerate | NodeIsTerminal) \ 308 macro(ThrowReferenceError, NodeMustGenerate | NodeIsTerminal) 308 macro(ThrowReferenceError, NodeMustGenerate | NodeIsTerminal) \ 309 \ 310 /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\ 311 /* this point, but execution does continue in the basic block - just in a */\ 312 /* different compiler. */\ 313 macro(ForceOSRExit, NodeMustGenerate) 309 314 310 315 // This enum generates a monotonically increasing id for all Node types, -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r95901 r95916 607 607 case Throw: 608 608 case ThrowReferenceError: 609 case ForceOSRExit: 609 610 break; 610 611 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r95910 r95916 2090 2090 break; 2091 2091 } 2092 2093 case ForceOSRExit: { 2094 terminateSpeculativeExecution(); 2095 break; 2096 } 2092 2097 2093 2098 case Phantom: -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r95901 r95916 211 211 if (m_canBeOptimized) 212 212 m_jitCodeMapEncoder.append(m_bytecodeOffset, differenceBetween(m_startOfCode, label())); 213 #endif 214 215 #if ENABLE(JIT_VERBOSE) 216 printf("Old JIT emitting code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, differenceBetween(m_startOfCode, label())); 213 217 #endif 214 218 … … 421 425 #endif 422 426 427 #if ENABLE(JIT_VERBOSE) 428 printf("Old JIT emitting slow code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, differenceBetween(m_startOfCode, label())); 429 #endif 430 423 431 switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) { 424 432 DEFINE_SLOWCASE_OP(op_add) … … 672 680 *functionEntryArityCheck = patchBuffer.locationOf(arityCheck); 673 681 674 return JITCode(patchBuffer.finalizeCode(), JITCode::BaselineJIT); 682 CodeRef result = patchBuffer.finalizeCode(); 683 684 #if ENABLE(JIT_VERBOSE) 685 printf("JIT generated code for %p at [%p, %p).\n", m_codeBlock, result.executableMemory()->start(), result.executableMemory()->end()); 686 #endif 687 688 return JITCode(result, JITCode::BaselineJIT); 675 689 } 676 690 -
trunk/Source/JavaScriptCore/jit/JIT.h
r95901 r95916 29 29 #if ENABLE(JIT) 30 30 31 // Verbose logging of code generation 32 #define ENABLE_JIT_VERBOSE 0 31 33 // Verbose logging for OSR-related code. 32 34 #define ENABLE_JIT_VERBOSE_OSR 0
Note: See TracChangeset
for help on using the changeset viewer.