2008-07-17 Geoffrey Garen <ggaren@apple.com>
+ Reviewed by Oliver Hunt.
+
+ Next step toward putting doubles in registers: Store constant pool
+ entries as registers, not JSValue*s.
+
+ SunSpider reports no change.
+
+2008-07-17 Geoffrey Garen <ggaren@apple.com>
+
Reviewed by John Sullivan and Oliver Hunt.
A tiny bit of tidying in function call register allocation.
(KJS::Register::):
(KJS::Register::Register):
-2008-07-16 Geoffrey Garen <ggaren@apple.com>
+2008-07-17 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
return result;
}
-static UString valueToSourceString(ExecState* exec, JSValue* val)
+static UString valueToSourceString(ExecState* exec, const Register& val)
{
- if (val->isString()) {
+ if (val.isString()) {
UString result("\"");
- result += escapeQuotes(val->toString(exec)) + "\"";
+ result += escapeQuotes(val.toString(exec)) + "\"";
return result;
}
- return val->toString(exec);
+ return val.toString(exec);
}
static CString registerName(int r)
return (UString("tr") + UString::from(r)).UTF8String();
}
-static CString constantName(ExecState* exec, int k, JSValue* value)
+static CString constantName(ExecState* exec, int k, const Register& value)
{
return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();
}
} while (i != identifiers.size());
}
- if (jsValues.size()) {
+ if (registers.size()) {
printf("\nConstants:\n");
size_t i = 0;
do {
- printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, jsValues[i]).ascii());
+ printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, registers[i]).ascii());
++i;
- } while (i < jsValues.size());
+ } while (i < registers.size());
}
if (regexps.size()) {
case op_load: {
int r0 = (++it)->u.operand;
int k0 = (++it)->u.operand;
- printf("[%4d] load\t\t %s, %s\t\t\n", location, registerName(r0).c_str(), constantName(exec, k0, jsValues[k0]).c_str());
+ printf("[%4d] load\t\t %s, %s\t\t\n", location, registerName(r0).c_str(), constantName(exec, k0, registers[k0]).c_str());
break;
}
case op_new_object: {
int r0 = (++it)->u.operand;
int errorType = (++it)->u.operand;
int k0 = (++it)->u.operand;
- printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(r0).c_str(), errorType, constantName(exec, k0, jsValues[k0]).c_str());
+ printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(r0).c_str(), errorType, constantName(exec, k0, registers[k0]).c_str());
break;
}
case op_jsr: {
void CodeBlock::mark()
{
- for (size_t i = 0; i < jsValues.size(); ++i)
- if (!jsValues[i]->marked())
- jsValues[i]->mark();
+ for (size_t i = 0; i < registers.size(); ++i)
+ if (!registers[i].marked())
+ registers[i].mark();
for (size_t i = 0; i < functions.size(); ++i)
functions[i]->body()->mark();
Vector<Identifier> identifiers;
Vector<RefPtr<FuncDeclNode> > functions;
Vector<RefPtr<FuncExprNode> > functionExpressions;
- Vector<JSValue*> jsValues;
+ Vector<Register> registers;
Vector<RefPtr<RegExp> > regexps;
Vector<HandlerInfo> exceptionHandlers;
Vector<LineInfo> lineInfo;
unsigned CodeGenerator::addConstant(JSValue* v)
{
- pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(v, m_codeBlock->jsValues.size());
+ pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(v, m_codeBlock->registers.size());
if (result.second) // new entry
- m_codeBlock->jsValues.append(v);
+ m_codeBlock->registers.append(v);
return result.first->second;
}
#endif
}
-NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock, JSValue**& k, ScopeChainNode*& scopeChain, Register*& r)
+NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock, Register*& k, ScopeChainNode*& scopeChain, Register*& r)
{
CodeBlock* oldCodeBlock = codeBlock;
Register* callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
if (!codeBlock)
return false;
- k = codeBlock->jsValues.data();
+ k = codeBlock->registers.data();
scopeChain = callFrame[RegisterFile::CallerScopeChain].scopeChain();
r = callFrame[RegisterFile::CallerRegisters].r();
exec->m_callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
return true;
}
-NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue* exceptionValue, const Instruction* vPC, CodeBlock*& codeBlock, JSValue**& k, ScopeChainNode*& scopeChain, Register*& r)
+NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue* exceptionValue, const Instruction* vPC, CodeBlock*& codeBlock, Register*& k, ScopeChainNode*& scopeChain, Register*& r)
{
// Set up the exception object
Register* registerBase = registerFile->base();
Instruction* vPC = codeBlock->instructions.begin();
- JSValue** k = codeBlock->jsValues.data();
+ Register* k = codeBlock->registers.data();
Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
codeBlock = newCodeBlock;
setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, r));
- k = codeBlock->jsValues.data();
+ k = codeBlock->registers.data();
vPC = codeBlock->instructions.begin();
#if DUMP_OPCODE_STATS
if (!codeBlock)
return returnValue;
- k = codeBlock->jsValues.data();
+ k = codeBlock->registers.data();
vPC = callFrame[RegisterFile::ReturnVPC].vPC();
setScopeChain(exec, scopeChain, callFrame[RegisterFile::CallerScopeChain].scopeChain());
r = callFrame[RegisterFile::CallerRegisters].r();
codeBlock = newCodeBlock;
setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, r));
- k = codeBlock->jsValues.data();
+ k = codeBlock->registers.data();
vPC = codeBlock->instructions.begin();
NEXT_OPCODE;
int type = (++vPC)->u.operand;
int message = (++vPC)->u.operand;
- r[dst] = Error::create(exec, (ErrorType)type, k[message]->toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL());
+ r[dst] = Error::create(exec, (ErrorType)type, k[message].toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL());
++vPC;
NEXT_OPCODE;
ALWAYS_INLINE void setScopeChain(ExecState* exec, ScopeChainNode*&, ScopeChainNode*);
NEVER_INLINE void debug(ExecState*, const Instruction*, const CodeBlock*, ScopeChainNode*, Register*);
- NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, const Instruction*&, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&);
- NEVER_INLINE Instruction* throwException(ExecState*, JSValue*, const Instruction*, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&);
+ NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, const Instruction*&, CodeBlock*&, Register*&, ScopeChainNode*&, Register*&);
+ NEVER_INLINE Instruction* throwException(ExecState*, JSValue*, const Instruction*, CodeBlock*&, Register*&, ScopeChainNode*&, Register*&);
Register* callFrame(ExecState*, JSFunction*) const;
bool marked() const;
void mark();
+ bool isString() const;
+
uint32_t toUInt32(ExecState*) const;
UString toString(ExecState*) const;
+
private:
friend class Machine;
jsValue()->mark();
}
+ ALWAYS_INLINE bool Register::isString() const
+ {
+ return jsValue()->isString();
+ }
+
ALWAYS_INLINE uint32_t Register::toUInt32(ExecState* exec) const
{
return jsValue()->toUInt32(exec);