Changeset 60512 in webkit for trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
- Timestamp:
- Jun 1, 2010, 4:13:23 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r60117 r60512 358 358 FunctionParameters& parameters = *functionBody->parameters(); 359 359 size_t parameterCount = parameters.size(); 360 m_nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;360 int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1; 361 361 m_parameters.grow(1 + parameterCount); // reserve space for "this" 362 362 363 363 // Add "this" as a parameter 364 m_thisRegister.setIndex(m_nextParameterIndex); 365 ++m_nextParameterIndex; 364 m_thisRegister.setIndex(nextParameterIndex); 366 365 ++m_codeBlock->m_numParameters; 367 366 368 367 for (size_t i = 0; i < parameterCount; ++i) 369 addParameter(parameters[i] );368 addParameter(parameters[i], ++nextParameterIndex); 370 369 371 370 preserveLastVar(); … … 432 431 } 433 432 434 RegisterID* BytecodeGenerator::addParameter(const Identifier& ident)433 void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex) 435 434 { 436 435 // Parameters overwrite var declarations, but not function declarations. 437 RegisterID* result = 0;438 436 UString::Rep* rep = ident.ustring().rep(); 439 437 if (!m_functions.contains(rep)) { 440 symbolTable().set(rep, m_nextParameterIndex); 441 RegisterID& parameter = registerFor(m_nextParameterIndex); 442 parameter.setIndex(m_nextParameterIndex); 443 result = ¶meter; 438 symbolTable().set(rep, parameterIndex); 439 RegisterID& parameter = registerFor(parameterIndex); 440 parameter.setIndex(parameterIndex); 444 441 } 445 442 446 443 // To maintain the calling convention, we have to allocate unique space for 447 444 // each parameter, even if the parameter doesn't make it into the symbol table. 448 ++m_nextParameterIndex;449 445 ++m_codeBlock->m_numParameters; 450 return result;451 446 } 452 447 … … 1416 1411 } 1417 1412 1418 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)1419 { 1420 return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);1413 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 1414 { 1415 return emitCall(op_call, dst, func, callArguments, divot, startOffset, endOffset); 1421 1416 } 1422 1417 … … 1431 1426 } 1432 1427 1433 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)1434 { 1435 return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);1436 } 1437 1438 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)1428 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 1429 { 1430 return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset); 1431 } 1432 1433 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 1439 1434 { 1440 1435 ASSERT(opcodeID == op_call || opcodeID == op_call_eval); 1441 1436 ASSERT(func->refCount()); 1442 ASSERT(thisRegister->refCount()); 1443 1444 RegisterID* originalFunc = func; 1445 if (m_shouldEmitProfileHooks) { 1446 // If codegen decided to recycle func as this call's destination register, 1447 // we need to undo that optimization here so that func will still be around 1448 // for the sake of op_profile_did_call. 1449 if (dst == func) { 1450 RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister); 1451 RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func); 1452 1453 thisRegister = movedThisRegister.release().releaseRef(); 1454 func = movedFunc.release().releaseRef(); 1455 } 1456 } 1437 1438 if (m_shouldEmitProfileHooks) 1439 emitMove(callArguments.profileHookRegister(), func); 1457 1440 1458 1441 // Generate code for arguments. 1459 Vector<RefPtr<RegisterID>, 16> argv; 1460 argv.append(thisRegister); 1461 for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) { 1462 argv.append(newTemporary()); 1463 // op_call requires the arguments to be a sequential range of registers 1464 ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1); 1465 emitNode(argv.last().get(), n); 1466 } 1442 unsigned argumentIndex = 0; 1443 for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next) 1444 emitNode(callArguments.argumentRegister(argumentIndex++), n); 1467 1445 1468 1446 // Reserve space for call frame. … … 1473 1451 if (m_shouldEmitProfileHooks) { 1474 1452 emitOpcode(op_profile_will_call); 1475 instructions().append( func->index());1453 instructions().append(callArguments.profileHookRegister()->index()); 1476 1454 1477 1455 #if ENABLE(JIT) 1478 m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());1456 m_codeBlock->addFunctionRegisterInfo(instructions().size(), callArguments.profileHookRegister()->index()); 1479 1457 #endif 1480 1458 } … … 1489 1467 emitOpcode(opcodeID); 1490 1468 instructions().append(func->index()); // func 1491 instructions().append( argv.size()); // argCount1492 instructions().append( argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset1469 instructions().append(callArguments.count()); // argCount 1470 instructions().append(callArguments.callFrame()); // registerOffset 1493 1471 if (dst != ignoredResult()) { 1494 1472 emitOpcode(op_call_put_result); … … 1498 1476 if (m_shouldEmitProfileHooks) { 1499 1477 emitOpcode(op_profile_did_call); 1500 instructions().append(func->index()); 1501 1502 if (dst == originalFunc) { 1503 thisRegister->deref(); 1504 func->deref(); 1505 } 1478 instructions().append(callArguments.profileHookRegister()->index()); 1506 1479 } 1507 1480 … … 1580 1553 } 1581 1554 1582 RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)1555 RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 1583 1556 { 1584 1557 ASSERT(func->refCount()); 1585 1558 1586 RegisterID* originalFunc = func; 1587 if (m_shouldEmitProfileHooks) { 1588 // If codegen decided to recycle func as this call's destination register, 1589 // we need to undo that optimization here so that func will still be around 1590 // for the sake of op_profile_did_call. 1591 if (dst == func) { 1592 RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func); 1593 func = movedFunc.release().releaseRef(); 1594 } 1595 } 1559 if (m_shouldEmitProfileHooks) 1560 emitMove(callArguments.profileHookRegister(), func); 1596 1561 1597 1562 // Generate code for arguments. 1598 Vector<RefPtr<RegisterID>, 16> argv; 1599 argv.append(newTemporary()); // reserve space for "this" 1600 for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode : 0; n; n = n->m_next) { 1601 argv.append(newTemporary()); 1602 // op_construct requires the arguments to be a sequential range of registers 1603 ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1); 1604 emitNode(argv.last().get(), n); 1563 unsigned argumentIndex = 0; 1564 if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) { 1565 for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) 1566 emitNode(callArguments.argumentRegister(argumentIndex++), n); 1605 1567 } 1606 1568 1607 1569 if (m_shouldEmitProfileHooks) { 1608 1570 emitOpcode(op_profile_will_call); 1609 instructions().append( func->index());1571 instructions().append(callArguments.profileHookRegister()->index()); 1610 1572 } 1611 1573 … … 1623 1585 emitOpcode(op_construct); 1624 1586 instructions().append(func->index()); // func 1625 instructions().append( argv.size()); // argCount1626 instructions().append( argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset1587 instructions().append(callArguments.count()); // argCount 1588 instructions().append(callArguments.callFrame()); // registerOffset 1627 1589 if (dst != ignoredResult()) { 1628 1590 emitOpcode(op_call_put_result); … … 1632 1594 if (m_shouldEmitProfileHooks) { 1633 1595 emitOpcode(op_profile_did_call); 1634 instructions().append(func->index()); 1635 1636 if (dst == originalFunc) 1637 func->deref(); 1596 instructions().append(callArguments.profileHookRegister()->index()); 1638 1597 } 1639 1598
Note:
See TracChangeset
for help on using the changeset viewer.