Changeset 34851 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Jun 28, 2008, 8:50:49 AM (17 years ago)
Author:
Darin Adler
Message:

2008-06-28 Darin Adler <Darin Adler>

Reviewed by Oliver.

SunSpider says 0.8% faster.

  • VM/CodeBlock.cpp: (KJS::CodeBlock::dump): Added argv and argc parameters to new_array.
  • VM/Machine.cpp: (KJS::Machine::privateExecute): Ditto.
  • VM/CodeGenerator.cpp: (KJS::CodeGenerator::emitNewArray): Added.
  • VM/CodeGenerator.h: Added ElementNode* argument to emitNewArray.
  • kjs/nodes.cpp: (KJS::ArrayNode::emitCode): Pass the ElementNode to emitNewArray so it can be initialized with as many elements as possible. If the array doesn't have any holes in it, that's all that's needed. If there are holes, then emit some separate put operations for the other values in the array and for the length as needed.
  • kjs/nodes.h: Added some accessors to ElementNode so the code generator can iterate through elements and generate code to evaluate them. Now ArrayNode does not need to be a friend. Also took out some unused PlacementNewAdoptType constructors.
Location:
trunk/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r34850 r34851  
    112008-06-28  Darin Adler  <[email protected]>
    22
    3         Reviewed by Oliver Hunt.
     3        Reviewed by Oliver.
     4
     5        - https://bugs.webkit.org/show_bug.cgi?id=19787
     6          create most arrays from values in registers rather than with multiple put operations
     7
     8        SunSpider says 0.8% faster.
     9
     10        * VM/CodeBlock.cpp:
     11        (KJS::CodeBlock::dump): Added argv and argc parameters to new_array.
     12        * VM/Machine.cpp:
     13        (KJS::Machine::privateExecute): Ditto.
     14
     15        * VM/CodeGenerator.cpp:
     16        (KJS::CodeGenerator::emitNewArray): Added.
     17        * VM/CodeGenerator.h: Added ElementNode* argument to emitNewArray.
     18
     19        * kjs/nodes.cpp:
     20        (KJS::ArrayNode::emitCode): Pass the ElementNode to emitNewArray so it can be
     21        initialized with as many elements as possible. If the array doesn't have any
     22        holes in it, that's all that's needed. If there are holes, then emit some separate
     23        put operations for the other values in the array and for the length as needed.
     24
     25        * kjs/nodes.h: Added some accessors to ElementNode so the code generator can
     26        iterate through elements and generate code to evaluate them. Now ArrayNode does
     27        not need to be a friend. Also took out some unused PlacementNewAdoptType
     28        constructors.
     29
     302008-06-28  Darin Adler  <[email protected]>
     31
     32        Reviewed by Oliver.
    433
    534        * kjs/nodes.h: Remove obsolete PlacementNewAdopt constructors.
  • trunk/JavaScriptCore/VM/CodeBlock.cpp

    r34842 r34851  
    3131#include "CodeBlock.h"
    3232
     33#include "JSValue.h"
    3334#include "Machine.h"
    3435#include "debugger.h"
    35 #include "JSValue.h"
    3636#include <stdio.h>
    3737
     
    218218        }
    219219        case op_new_array: {
    220             int r0 = (++it)->u.operand;
    221             printf("[%4d] new_array\t %s\n", location, registerName(r0).c_str());
     220            int dst = (++it)->u.operand;
     221            int argv = (++it)->u.operand;
     222            int argc = (++it)->u.operand;
     223            printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(dst).c_str(), registerName(argv).c_str(), argc);
    222224            break;
    223225        }
  • trunk/JavaScriptCore/VM/CodeGenerator.cpp

    r34842 r34851  
    3131#include "CodeGenerator.h"
    3232
     33#include "JSFunction.h"
    3334#include "Machine.h"
    34 #include "JSFunction.h"
    3535
    3636using namespace std;
     
    792792}
    793793
    794 RegisterID* CodeGenerator::emitNewFunction(RegisterID* r0, FuncDeclNode* n)
     794RegisterID* CodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
     795{
     796    Vector<RefPtr<RegisterID>, 16> argv;
     797    for (ElementNode* n = elements; n; n = n->next()) {
     798        if (n->elision())
     799            break;
     800        argv.append(newTemporary());
     801        emitNode(argv.last().get(), n->value());
     802    }
     803    emitOpcode(op_new_array);
     804    instructions().append(dst->index());
     805    instructions().append(argv.size() ? argv[0]->index() : 0); // argv
     806    instructions().append(argv.size()); // argc
     807    return dst;
     808}
     809
     810RegisterID* CodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n)
    795811{
    796812    emitOpcode(op_new_func);
    797     instructions().append(r0->index());
     813    instructions().append(dst->index());
    798814    instructions().append(addConstant(n));
    799     return r0;
     815    return dst;
    800816}
    801817
  • trunk/JavaScriptCore/VM/CodeGenerator.h

    r34838 r34851  
    200200
    201201        RegisterID* emitNewObject(RegisterID* dst) { return emitNullaryOp(op_new_object, dst); }
    202         RegisterID* emitNewArray(RegisterID* dst) { return emitNullaryOp(op_new_array, dst); }
     202        RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision
    203203
    204204        RegisterID* emitNewFunction(RegisterID* dst, FuncDeclNode* func);
  • trunk/JavaScriptCore/VM/Machine.cpp

    r34849 r34851  
    3636#include "ExecState.h"
    3737#include "JSActivation.h"
     38#include "JSArray.h"
     39#include "JSFunction.h"
    3840#include "JSLock.h"
    3941#include "JSPropertyNameIterator.h"
     42#include "JSString.h"
    4043#include "Parser.h"
    4144#include "Profiler.h"
     45#include "RegExpObject.h"
    4246#include "Register.h"
    43 #include "JSArray.h"
    4447#include "debugger.h"
    45 #include "JSFunction.h"
    46 #include "JSString.h"
    4748#include "object_object.h"
    4849#include "operations.h"
    49 #include "RegExpObject.h"
    50 
    5150#include <stdio.h>
    5251
     
    10371036    }
    10381037    BEGIN_OPCODE(op_new_array) {
    1039         /* new_array dst(r)
    1040 
    1041            Constructs a new empty Array instance using the original
     1038        /* new_array dst(r) firstArg(r) argCount(n)
     1039
     1040           Constructs a new Array instance using the original
    10421041           constructor, and puts the result in register dst.
    1043         */
    1044         int dst = (++vPC)->u.operand;
    1045         r[dst].u.jsValue = constructEmptyArray(exec);
     1042           The array will contain argCount elements with values
     1043           taken from registers starting at register firstArg.
     1044        */
     1045        int dst = (++vPC)->u.operand;
     1046        int firstArg = (++vPC)->u.operand;
     1047        int argCount = (++vPC)->u.operand;
     1048        ArgList args(reinterpret_cast<JSValue***>(&registerBase), r - registerBase + firstArg, argCount);
     1049        r[dst].u.jsValue = constructArray(exec, args);
    10461050
    10471051        ++vPC;
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r34843 r34851  
    4848namespace KJS {
    4949
    50 static inline UString::Rep* rep(const Identifier& ident)
    51 {
    52     return ident.ustring().rep();
    53 }
    54 
    5550// ------------------------------ Node -----------------------------------------
    5651
    5752#ifndef NDEBUG
     53
    5854#ifndef LOG_CHANNEL_PREFIX
    5955#define LOG_CHANNEL_PREFIX Log
    6056#endif
     57
    6158static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn };
    6259
     
    10097    --count;
    10198}
     99
    102100#endif
    103101
     
    215213}
    216214
    217 static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
    218 static inline int currentSourceId(ExecState*)
    219 {
    220     ASSERT_NOT_REACHED();
    221     return 0;
    222 }
    223 
    224 static inline const UString currentSourceURL(ExecState* exec) KJS_FAST_CALL;
    225 static inline const UString currentSourceURL(ExecState*)
    226 {
    227     ASSERT_NOT_REACHED();
    228     return UString();
    229 }
    230 
    231215RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
    232216{
     
    346330// ------------------------------ ArrayNode ------------------------------------
    347331
    348 
    349332RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    350333{
    351     RefPtr<RegisterID> newArray = generator.emitNewArray(generator.tempDestination(dst));
     334    // FIXME: Should we put all of this code into emitNewArray?
     335
    352336    unsigned length = 0;
    353 
    354     RegisterID* value;
    355     for (ElementNode* n = m_element.get(); n; n = n->m_next.get()) {
    356         value = generator.emitNode(n->m_node.get());
    357         length += n->m_elision;
    358         generator.emitPutByIndex(newArray.get(), length++, value);
    359     }
    360 
    361     value = generator.emitLoad(generator.newTemporary(), jsNumber(generator.globalExec(), m_elision + length));
    362     generator.emitPutById(newArray.get(), generator.propertyNames().length, value);
    363 
    364     return generator.moveToDestinationIfNeeded(dst, newArray.get());
     337    ElementNode* firstPutElement;
     338    for (firstPutElement = m_element.get(); firstPutElement; firstPutElement = firstPutElement->next()) {
     339        if (firstPutElement->elision())
     340            break;
     341        ++length;
     342    }
     343
     344    if (!firstPutElement && !m_elision)
     345        return generator.emitNewArray(generator.finalDestination(dst), m_element.get());
     346
     347    RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element.get());
     348
     349    for (ElementNode* n = firstPutElement; n; n = n->next()) {
     350        RegisterID* value = generator.emitNode(n->value());
     351        length += n->elision();
     352        generator.emitPutByIndex(array.get(), length++, value);
     353    }
     354
     355    if (m_elision) {
     356        RegisterID* value = generator.emitLoad(generator.newTemporary(), jsNumber(generator.globalExec(), m_elision + length));
     357        generator.emitPutById(array.get(), generator.propertyNames().length, value);
     358    }
     359
     360    return generator.moveToDestinationIfNeeded(dst, array.get());
    365361}
    366362
     
    371367    if (m_list)
    372368        return generator.emitNode(dst, m_list.get());
    373     else
    374         return generator.emitNewObject(generator.finalDestination(dst));
     369    return generator.emitNewObject(generator.finalDestination(dst));
    375370}
    376371
  • trunk/JavaScriptCore/kjs/nodes.h

    r34850 r34851  
    3030#include "LabelStack.h"
    3131#include "Opcode.h"
    32 #include "regexp.h"
    3332#include "RegisterID.h"
    3433#include "SourceRange.h"
    3534#include "SymbolTable.h"
    36 #include <wtf/UnusedParam.h>
     35#include "regexp.h"
    3736#include <wtf/ListRefPtr.h>
    3837#include <wtf/MathExtras.h>
    3938#include <wtf/OwnPtr.h>
     39#include <wtf/UnusedParam.h>
    4040#include <wtf/Vector.h>
    4141
     
    4848namespace KJS {
    4949
    50     class ArgumentsNode;
    5150    class CodeBlock;
    5251    class CodeGenerator;
    53     class ConstDeclNode;
    5452    class FuncDeclNode;
    5553    class Node;
     
    390388        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    391389
     390        int elision() const { return m_elision; }
     391        ExpressionNode* value() { return m_node.get(); }
     392
     393        ElementNode* next() { return m_next.get(); }
    392394        PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
    393395
    394396    private:
    395         friend class ArrayNode;
    396397        ListRefPtr<ElementNode> m_next;
    397398        int m_elision;
Note: See TracChangeset for help on using the changeset viewer.