Changeset 27252 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp


Ignore:
Timestamp:
Oct 29, 2007, 8:14:00 PM (18 years ago)
Author:
oliver
Message:

Debranching various Node::evaluate implementations

Reviewed by Maciej.

Split the read-modify-write assignment cases out of AssignResolveNode and into ReadModifyResolveNode
Split the increment and decrement cases for Prefix- and Postfix- ResolveNode, BracketNode, and DotNode

Gains 1.6% on SunSpider

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r27242 r27252  
    893893// ------------------------------ PostfixResolveNode ----------------------------------
    894894
    895 void PostfixResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
     895// Increment
     896void PostIncResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
    896897{
    897898    size_t index = functionBody->symbolTable().get(m_ident.ustring().rep());
    898899    if (index != missingSymbolMarker())
    899         new (this) LocalVarPostfixNode(index);
    900 }
    901 
    902 JSValue *PostfixResolveNode::evaluate(ExecState *exec)
     900        new (this) PostIncLocalVarNode(index);
     901}
     902
     903JSValue *PostIncResolveNode::evaluate(ExecState *exec)
    903904{
    904905  // Check for missed optimization opportunity.
     
    920921
    921922        double n = v->toNumber(exec);
    922        
    923         double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    924         base->put(exec, m_ident, jsNumber(newValue));
    925        
     923        base->put(exec, m_ident, jsNumber(n + 1));
    926924        return jsNumber(n);
    927925    }
     
    933931}
    934932
    935 JSValue* LocalVarPostfixNode::evaluate(ExecState* exec)
     933JSValue* PostIncLocalVarNode::evaluate(ExecState* exec)
    936934{
    937935    ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject());
     
    941939    JSValue** slot = &variableObject->localStorage()[index].value;
    942940    double n = (*slot)->toNumber(exec);
    943     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    944     *slot = jsNumber(newValue);
     941    *slot = jsNumber(n + 1);
     942    return jsNumber(n);
     943}
     944
     945
     946// Decrement
     947void PostDecResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
     948{
     949    size_t index = functionBody->symbolTable().get(m_ident.ustring().rep());
     950    if (index != missingSymbolMarker())
     951        new (this) PostDecLocalVarNode(index);
     952}
     953
     954JSValue *PostDecResolveNode::evaluate(ExecState *exec)
     955{
     956  // Check for missed optimization opportunity.
     957  ASSERT(!canSkipLookup(exec, m_ident));
     958
     959  const ScopeChain& chain = exec->scopeChain();
     960  ScopeChainIterator iter = chain.begin();
     961  ScopeChainIterator end = chain.end();
     962 
     963  // we must always have something in the scope chain
     964  ASSERT(iter != end);
     965
     966  PropertySlot slot;
     967  JSObject *base;
     968  do {
     969    base = *iter;
     970    if (base->getPropertySlot(exec, m_ident, slot)) {
     971        JSValue *v = slot.getValue(exec, base, m_ident);
     972
     973        double n = v->toNumber(exec);
     974        base->put(exec, m_ident, jsNumber(n - 1));
     975        return jsNumber(n);
     976    }
     977
     978    ++iter;
     979  } while (iter != end);
     980
     981  return throwUndefinedVariableError(exec, m_ident);
     982}
     983
     984JSValue* PostDecLocalVarNode::evaluate(ExecState* exec)
     985{
     986    ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject());
     987    ASSERT(variableObject->isActivation());
     988    ASSERT(variableObject == exec->scopeChain().top());
     989
     990    JSValue** slot = &variableObject->localStorage()[index].value;
     991    double n = (*slot)->toNumber(exec);
     992    *slot = jsNumber(n - 1);
    945993    return jsNumber(n);
    946994}
     
    9541002}
    9551003
    956 JSValue *PostfixBracketNode::evaluate(ExecState *exec)
     1004JSValue *PostIncBracketNode::evaluate(ExecState *exec)
    9571005{
    9581006  JSValue *baseValue = m_base->evaluate(exec);
     
    9711019    double n = v->toNumber(exec);
    9721020
    973     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    974     base->put(exec, propertyIndex, jsNumber(newValue));
     1021    base->put(exec, propertyIndex, jsNumber(n + 1));
    9751022       
    9761023    return jsNumber(n);
     
    9841031  double n = v->toNumber(exec);
    9851032 
    986   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    987   base->put(exec, propertyName, jsNumber(newValue));
     1033  base->put(exec, propertyName, jsNumber(n + 1));
    9881034       
    9891035  return jsNumber(n);
    9901036}
    9911037
     1038JSValue *PostDecBracketNode::evaluate(ExecState *exec)
     1039{
     1040  JSValue *baseValue = m_base->evaluate(exec);
     1041  KJS_CHECKEXCEPTIONVALUE
     1042  JSValue *subscript = m_subscript->evaluate(exec);
     1043  KJS_CHECKEXCEPTIONVALUE
     1044
     1045  JSObject *base = baseValue->toObject(exec);
     1046
     1047  uint32_t propertyIndex;
     1048  if (subscript->getUInt32(propertyIndex)) {
     1049    PropertySlot slot;
     1050    JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
     1051    KJS_CHECKEXCEPTIONVALUE
     1052
     1053    double n = v->toNumber(exec);
     1054
     1055    base->put(exec, propertyIndex, jsNumber(n - 1));
     1056       
     1057    return jsNumber(n);
     1058  }
     1059
     1060  Identifier propertyName(subscript->toString(exec));
     1061  PropertySlot slot;
     1062  JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
     1063  KJS_CHECKEXCEPTIONVALUE
     1064
     1065  double n = v->toNumber(exec);
     1066 
     1067  base->put(exec, propertyName, jsNumber(n - 1));
     1068       
     1069  return jsNumber(n);
     1070}
     1071
    9921072// ------------------------------ PostfixDotNode ----------------------------------
    9931073
     
    9971077}
    9981078
    999 JSValue *PostfixDotNode::evaluate(ExecState *exec)
     1079JSValue *PostIncDotNode::evaluate(ExecState *exec)
    10001080{
    10011081  JSValue *baseValue = m_base->evaluate(exec);
     
    10091089  double n = v->toNumber(exec);
    10101090 
    1011   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    1012   base->put(exec, m_ident, jsNumber(newValue));
     1091  base->put(exec, m_ident, jsNumber(n + 1));
     1092       
     1093  return jsNumber(n);
     1094}
     1095
     1096JSValue *PostDecDotNode::evaluate(ExecState *exec)
     1097{
     1098  JSValue *baseValue = m_base->evaluate(exec);
     1099  KJS_CHECKEXCEPTIONVALUE
     1100  JSObject *base = baseValue->toObject(exec);
     1101
     1102  PropertySlot slot;
     1103  JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
     1104  KJS_CHECKEXCEPTIONVALUE
     1105
     1106  double n = v->toNumber(exec);
     1107 
     1108  base->put(exec, m_ident, jsNumber(n - 1));
    10131109       
    10141110  return jsNumber(n);
     
    12301326// ------------------------------ PrefixResolveNode ----------------------------------
    12311327
    1232 void PrefixResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
     1328void PreIncResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
    12331329{
    12341330    size_t index = functionBody->symbolTable().get(m_ident.ustring().rep());
    12351331    if (index != missingSymbolMarker())
    1236         new (this) LocalVarPrefixNode(index);
    1237 }
    1238 
    1239 JSValue* LocalVarPrefixNode::evaluate(ExecState* exec)
     1332        new (this) PreIncLocalVarNode(index);
     1333}
     1334
     1335JSValue* PreIncLocalVarNode::evaluate(ExecState* exec)
    12401336{
    12411337    ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject());
     
    12451341
    12461342    double n = v->toNumber(exec);
    1247        
    1248     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    1249     JSValue* n2 = jsNumber(newValue);
     1343    JSValue* n2 = jsNumber(n + 1);
    12501344    variableObject->localStorage()[m_index].value = n2;
    12511345    return n2;
    12521346}
    12531347
    1254 JSValue *PrefixResolveNode::evaluate(ExecState *exec)
     1348JSValue *PreIncResolveNode::evaluate(ExecState *exec)
    12551349{
    12561350  const ScopeChain& chain = exec->scopeChain();
     
    12691363
    12701364        double n = v->toNumber(exec);
    1271        
    1272         double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    1273         JSValue *n2 = jsNumber(newValue);
     1365        JSValue *n2 = jsNumber(n + 1);
    12741366        base->put(exec, m_ident, n2);
    12751367
     
    12831375}
    12841376
     1377void PreDecResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
     1378{
     1379    size_t index = functionBody->symbolTable().get(m_ident.ustring().rep());
     1380    if (index != missingSymbolMarker())
     1381        new (this) PreDecLocalVarNode(index);
     1382}
     1383
     1384JSValue* PreDecLocalVarNode::evaluate(ExecState* exec)
     1385{
     1386    ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject());
     1387    ASSERT(variableObject->isActivation());
     1388    ASSERT(variableObject == exec->scopeChain().top());
     1389    JSValue* v = variableObject->localStorage()[m_index].value;
     1390
     1391    double n = v->toNumber(exec);
     1392    JSValue* n2 = jsNumber(n - 1);
     1393    variableObject->localStorage()[m_index].value = n2;
     1394    return n2;
     1395}
     1396
     1397JSValue *PreDecResolveNode::evaluate(ExecState *exec)
     1398{
     1399  const ScopeChain& chain = exec->scopeChain();
     1400  ScopeChainIterator iter = chain.begin();
     1401  ScopeChainIterator end = chain.end();
     1402 
     1403  // we must always have something in the scope chain
     1404  ASSERT(iter != end);
     1405
     1406  PropertySlot slot;
     1407  JSObject *base;
     1408  do {
     1409    base = *iter;
     1410    if (base->getPropertySlot(exec, m_ident, slot)) {
     1411        JSValue *v = slot.getValue(exec, base, m_ident);
     1412
     1413        double n = v->toNumber(exec);
     1414        JSValue *n2 = jsNumber(n - 1);
     1415        base->put(exec, m_ident, n2);
     1416
     1417        return n2;
     1418    }
     1419
     1420    ++iter;
     1421  } while (iter != end);
     1422
     1423  return throwUndefinedVariableError(exec, m_ident);
     1424}
     1425
    12851426// ------------------------------ PrefixBracketNode ----------------------------------
    12861427
     
    12911432}
    12921433
    1293 JSValue *PrefixBracketNode::evaluate(ExecState *exec)
     1434JSValue *PreIncBracketNode::evaluate(ExecState *exec)
    12941435{
    12951436  JSValue *baseValue = m_base->evaluate(exec);
     
    13061447    KJS_CHECKEXCEPTIONVALUE
    13071448
    1308     double n = v->toNumber(exec);
    1309 
    1310     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    1311     JSValue *n2 = jsNumber(newValue);
     1449    JSValue *n2 = jsNumber(v->toNumber(exec) + 1);
    13121450    base->put(exec, propertyIndex, n2);
    13131451
     
    13201458  KJS_CHECKEXCEPTIONVALUE
    13211459
    1322   double n = v->toNumber(exec);
    1323  
    1324   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    1325   JSValue *n2 = jsNumber(newValue);
     1460  JSValue *n2 = jsNumber(v->toNumber(exec) + 1);
    13261461  base->put(exec, propertyName, n2);
    13271462
     
    13291464}
    13301465
     1466JSValue *PreDecBracketNode::evaluate(ExecState *exec)
     1467{
     1468  JSValue *baseValue = m_base->evaluate(exec);
     1469  KJS_CHECKEXCEPTIONVALUE
     1470  JSValue *subscript = m_subscript->evaluate(exec);
     1471  KJS_CHECKEXCEPTIONVALUE
     1472
     1473  JSObject *base = baseValue->toObject(exec);
     1474
     1475  uint32_t propertyIndex;
     1476  if (subscript->getUInt32(propertyIndex)) {
     1477    PropertySlot slot;
     1478    JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
     1479    KJS_CHECKEXCEPTIONVALUE
     1480
     1481    JSValue *n2 = jsNumber(v->toNumber(exec) - 1);
     1482    base->put(exec, propertyIndex, n2);
     1483
     1484    return n2;
     1485  }
     1486
     1487  Identifier propertyName(subscript->toString(exec));
     1488  PropertySlot slot;
     1489  JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
     1490  KJS_CHECKEXCEPTIONVALUE
     1491
     1492  JSValue *n2 = jsNumber(v->toNumber(exec) - 1);
     1493  base->put(exec, propertyName, n2);
     1494
     1495  return n2;
     1496}
     1497
    13311498// ------------------------------ PrefixDotNode ----------------------------------
    13321499
     
    13361503}
    13371504
    1338 JSValue *PrefixDotNode::evaluate(ExecState *exec)
     1505JSValue *PreIncDotNode::evaluate(ExecState *exec)
    13391506{
    13401507  JSValue *baseValue = m_base->evaluate(exec);
     
    13471514
    13481515  double n = v->toNumber(exec);
    1349  
    1350   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
    1351   JSValue *n2 = jsNumber(newValue);
     1516  JSValue *n2 = jsNumber(n + 1);
     1517  base->put(exec, m_ident, n2);
     1518
     1519  return n2;
     1520}
     1521
     1522JSValue *PreDecDotNode::evaluate(ExecState *exec)
     1523{
     1524  JSValue *baseValue = m_base->evaluate(exec);
     1525  KJS_CHECKEXCEPTIONVALUE
     1526  JSObject *base = baseValue->toObject(exec);
     1527
     1528  PropertySlot slot;
     1529  JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
     1530  KJS_CHECKEXCEPTIONVALUE
     1531
     1532  double n = v->toNumber(exec);
     1533  JSValue *n2 = jsNumber(n - 1);
    13521534  base->put(exec, m_ident, n2);
    13531535
     
    19992181}
    20002182
    2001 // ------------------------------ AssignResolveNode -----------------------------------
    2002 
    2003 void AssignResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack& nodeStack)
     2183// ------------------------------ ReadModifyResolveNode -----------------------------------
     2184
     2185void ReadModifyResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack& nodeStack)
    20042186{
    20052187    nodeStack.append(m_right.get());
    20062188    size_t index = functionBody->symbolTable().get(m_ident.ustring().rep());
    20072189    if (index != missingSymbolMarker())
    2008         new (this) LocalVarAssignNode(index);
    2009 }
    2010 
    2011 JSValue* LocalVarAssignNode::evaluate(ExecState* exec)
     2190        new (this) ReadModifyLocalVarNode(index);
     2191}
     2192
     2193void AssignResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack& nodeStack)
     2194{
     2195    nodeStack.append(m_right.get());
     2196    size_t index = functionBody->symbolTable().get(m_ident.ustring().rep());
     2197    if (index != missingSymbolMarker())
     2198        new (this) AssignLocalVarNode(index);
     2199}
     2200
     2201JSValue* ReadModifyLocalVarNode::evaluate(ExecState* exec)
    20122202{
    20132203    ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject());
     
    20302220}
    20312221
    2032 JSValue *AssignResolveNode::evaluate(ExecState *exec)
     2222JSValue* AssignLocalVarNode::evaluate(ExecState* exec)
     2223{
     2224    ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject());
     2225    ASSERT(variableObject->isActivation());
     2226    ASSERT(variableObject == exec->scopeChain().top());
     2227    JSValue* v = m_right->evaluate(exec);
     2228
     2229    KJS_CHECKEXCEPTIONVALUE
     2230
     2231    variableObject->localStorage()[m_index].value = v;
     2232   
     2233    return v;
     2234}
     2235
     2236JSValue *ReadModifyResolveNode::evaluate(ExecState *exec)
    20332237{
    20342238  const ScopeChain& chain = exec->scopeChain();
     
    20632267    v = valueForReadModifyAssignment(exec, v1, v2, m_oper);
    20642268  }
     2269
     2270  KJS_CHECKEXCEPTIONVALUE
     2271
     2272  base->put(exec, m_ident, v);
     2273  return v;
     2274}
     2275
     2276JSValue *AssignResolveNode::evaluate(ExecState *exec)
     2277{
     2278  const ScopeChain& chain = exec->scopeChain();
     2279  ScopeChainIterator iter = chain.begin();
     2280  ScopeChainIterator end = chain.end();
     2281 
     2282  // we must always have something in the scope chain
     2283  ASSERT(iter != end);
     2284
     2285  PropertySlot slot;
     2286  JSObject *base;
     2287  do {
     2288    base = *iter;
     2289    if (base->getPropertySlot(exec, m_ident, slot))
     2290      goto found;
     2291
     2292    ++iter;
     2293  } while (iter != end);
     2294
     2295 found:
     2296  JSValue *v = m_right->evaluate(exec);
    20652297
    20662298  KJS_CHECKEXCEPTIONVALUE
Note: See TracChangeset for help on using the changeset viewer.