Changeset 36976 in webkit for trunk/JavaScriptCore/kjs/nodes.h


Ignore:
Timestamp:
Sep 26, 2008, 6:44:15 PM (17 years ago)
Author:
[email protected]
Message:

2008-09-26 Gavin Barraclough <[email protected]>

Reviewed by Maciej Stachowiak & Oliver Hunt.

Add support for reusing temporary JSNumberCells. This change is based on the observation
that if the result of certain operations is a JSNumberCell and is consumed by a subsequent
operation that would produce a JSNumberCell, we can reuse the object rather than allocating
a fresh one. E.g. given the expression ((a * b) * c), we can statically determine that
(a * b) will have a numeric result (or else it will have thrown an exception), so the result
will either be a JSNumberCell or a JSImmediate.

This patch changes three areas of JSC:

  • The AST now tracks type information about the result of each node.
  • This information is consumed in bytecode compilation, and certain bytecode operations now carry the statically determined type information about their operands.
  • CTI uses the information in a number of fashions:
    • Where an operand to certain arithmetic operations is reusable, it will plant code to try to perform the operation in JIT code & reuse the cell, where appropriate.
    • Where it can be statically determined that an operand can only be numeric (typically the result of another arithmetic operation) the code will not redundantly check that the JSCell is a JSNumberCell.
    • Where either of the operands to an add are non-numeric do not plant an optimized arithmetic code path, just call straight out to the C function.

+6% Sunspider (10% progression on 3D, 16% progression on math, 60% progression on access-nbody),
+1% v8-tests (improvements in raytrace & crypto)

  • VM/CTI.cpp: Add optimized code generation with reuse of temporary JSNumberCells.
  • VM/CTI.h:
  • kjs/JSNumberCell.h:
  • masm/X86Assembler.h:
  • VM/CodeBlock.cpp: Add type information to specific bytecodes.
  • VM/CodeGenerator.cpp:
  • VM/CodeGenerator.h:
  • VM/Machine.cpp:
  • kjs/nodes.cpp: Track static type information for nodes.
  • kjs/nodes.h:
  • kjs/ResultDescriptor.h: (Added)
  • JavaScriptCore.xcodeproj/project.pbxproj:
File:
1 edited

Legend:

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

    r36871 r36976  
    3333#include "Opcode.h"
    3434#include "RegisterID.h"
     35#include "ResultType.h"
    3536#include "SourceRange.h"
    3637#include "SymbolTable.h"
     
    194195       
    195196    protected:
    196         Node(JSGlobalData*, JSType) JSC_FAST_CALL; // used by ExpressionNode
    197 
    198         int m_line : 28;
    199         unsigned m_expectedReturnType : 3; // JSType
     197        int m_line;
    200198    };
    201199
    202200    class ExpressionNode : public Node {
    203201    public:
    204         ExpressionNode(JSGlobalData* globalData) JSC_FAST_CALL : Node(globalData) {}
    205         ExpressionNode(JSGlobalData* globalData, JSType expectedReturn) JSC_FAST_CALL
    206             : Node(globalData, expectedReturn)
     202        ExpressionNode(JSGlobalData* globalData, ResultType resultDesc = ResultType::unknown()) JSC_FAST_CALL
     203            : Node(globalData)
     204            , m_resultDesc(resultDesc)
    207205        {
    208206        }
     
    217215        virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
    218216
    219         JSType expectedReturnType() const JSC_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
     217        ResultType resultDescriptor() const JSC_FAST_CALL { return m_resultDesc; }
    220218
    221219        // This needs to be in public in order to compile using GCC 3.x
    222220        typedef enum { EvalOperator, FunctionCall } CallerType;
     221
     222    private:
     223        ResultType m_resultDesc;
    223224    };
    224225
     
    246247    public:
    247248        NullNode(JSGlobalData* globalData) JSC_FAST_CALL
    248             : ExpressionNode(globalData, NullType)
     249            : ExpressionNode(globalData, ResultType::nullType())
    249250        {
    250251        }
     
    261262    public:
    262263        BooleanNode(JSGlobalData* globalData, bool value) JSC_FAST_CALL
    263             : ExpressionNode(globalData, BooleanType)
     264            : ExpressionNode(globalData, ResultType::boolean())
    264265            , m_value(value)
    265266        {
     
    279280    public:
    280281        NumberNode(JSGlobalData* globalData, double v) JSC_FAST_CALL
    281             : ExpressionNode(globalData, NumberType)
     282            : ExpressionNode(globalData, ResultType::constNumber())
    282283            , m_double(v)
    283284        {
     
    316317    public:
    317318        StringNode(JSGlobalData* globalData, const Identifier& v) JSC_FAST_CALL
    318             : ExpressionNode(globalData, StringType)
     319            : ExpressionNode(globalData, ResultType::string())
    319320            , m_value(v)
    320321        {
     
    845846    public:
    846847        PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
    847             : ExpressionNode(globalData, NumberType)
     848            : ExpressionNode(globalData, ResultType::constNumber()) // could be reusable for pre?
    848849            , ThrowableExpressionData(divot, startOffset, endOffset)
    849850            , m_ident(ident)
     
    10271028    public:
    10281029        TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
    1029             : ExpressionNode(globalData, StringType)
     1030            : ExpressionNode(globalData, ResultType::string())
    10301031            , m_ident(ident)
    10311032        {
     
    10471048    public:
    10481049        TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
    1049             : ExpressionNode(globalData, StringType)
     1050            : ExpressionNode(globalData, ResultType::string())
    10501051            , m_expr(expr)
    10511052        {
     
    11471148        }
    11481149
    1149         UnaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* expr)
     1150        UnaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr)
    11501151            : ExpressionNode(globalData, type)
    11511152            , m_expr(expr)
     
    11631164    public:
    11641165        UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
    1165             : UnaryOpNode(globalData, NumberType, expr)
     1166            : UnaryOpNode(globalData, ResultType::constNumber(), expr)
    11661167        {
    11671168        }
     
    11751176    public:
    11761177        NegateNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
    1177             : UnaryOpNode(globalData, NumberType, expr)
     1178            : UnaryOpNode(globalData, ResultType::reusableNumber(), expr)
    11781179        {
    11791180        }
     
    11871188    public:
    11881189        BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
    1189             : UnaryOpNode(globalData, NumberType, expr)
     1190            : UnaryOpNode(globalData, ResultType::reusableNumber(), expr)
    11901191        {
    11911192        }
     
    11991200    public:
    12001201        LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
    1201             : UnaryOpNode(globalData, BooleanType, expr)
     1202            : UnaryOpNode(globalData, ResultType::boolean(), expr)
    12021203        {
    12031204        }
     
    12181219        }
    12191220
    1220         BinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     1221        BinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    12211222            : ExpressionNode(globalData, type)
    12221223            , m_expr1(expr1)
     
    12451246        }
    12461247
    1247         ReverseBinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
     1248        ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
    12481249            : ExpressionNode(globalData, type)
    12491250            , m_expr1(expr1)
     
    12651266    public:
    12661267        MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1267             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1268            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    12681269        {
    12691270        }
     
    12771278    public:
    12781279        DivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1279             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1280            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    12801281        {
    12811282        }
     
    12891290    public:
    12901291        ModNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1291             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1292            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    12921293        {
    12931294        }
     
    13011302    public:
    13021303        AddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1303             : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
     1304            : BinaryOpNode(globalData, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, rightHasAssignments)
    13041305        {
    13051306        }
     
    13131314    public:
    13141315        SubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1315             : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
     1316            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    13161317        {
    13171318        }
     
    13251326    public:
    13261327        LeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1327             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1328            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    13281329        {
    13291330        }
     
    13371338    public:
    13381339        RightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1339             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1340            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    13401341        {
    13411342        }
     
    13491350    public:
    13501351        UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1351             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1352            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    13521353        {
    13531354        }
     
    13611362    public:
    13621363        LessNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1363             : BinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1364            : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    13641365        {
    13651366        }
     
    13731374    public:
    13741375        GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1375             : ReverseBinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1376            : ReverseBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    13761377        {
    13771378        }
     
    13851386    public:
    13861387        LessEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1387             : BinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1388            : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    13881389        {
    13891390        }
     
    13971398    public:
    13981399        GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1399             : ReverseBinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1400            : ReverseBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    14001401        {
    14011402        }
     
    14081409    class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
    14091410    public:
    1410         ThrowableBinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
     1411        ThrowableBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    14111412            : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
    14121413        {
     
    14221423    public:
    14231424        InstanceOfNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1424             : ThrowableBinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1425            : ThrowableBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    14251426        {
    14261427        }
     
    14481449    public:
    14491450        EqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1450             : BinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1451            : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    14511452        {
    14521453        }
     
    14611462    public:
    14621463        NotEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1463             : BinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1464            : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    14641465        {
    14651466        }
     
    14731474    public:
    14741475        StrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1475             : BinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1476            : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    14761477        {
    14771478        }
     
    14861487    public:
    14871488        NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1488             : BinaryOpNode(globalData, BooleanType, expr1, expr2, rightHasAssignments)
     1489            : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
    14891490        {
    14901491        }
     
    14981499    public:
    14991500        BitAndNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1500             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1501            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    15011502        {
    15021503        }
     
    15101511    public:
    15111512        BitOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1512             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1513            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    15131514        {
    15141515        }
     
    15221523    public:
    15231524        BitXOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
    1524             : BinaryOpNode(globalData, NumberType, expr1, expr2, rightHasAssignments)
     1525            : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
    15251526        {
    15261527        }
     
    15371538    public:
    15381539        LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper) JSC_FAST_CALL
    1539             : ExpressionNode(globalData, BooleanType)
     1540            : ExpressionNode(globalData, ResultType::boolean())
    15401541            , m_expr1(expr1)
    15411542            , m_expr2(expr2)
Note: See TracChangeset for help on using the changeset viewer.