source: webkit/trunk/JavaScriptCore/kjs/operations.h@ 37086

Last change on this file since 37086 was 36876, checked in by [email protected], 17 years ago

2008-09-24 Maciej Stachowiak <[email protected]>

Reviewed by Oliver Hunt.


  • inline JIT fast case of op_neq
  • remove extra level of function call indirection from slow cases of eq and neq


1% speedup on Richards

  • VM/CTI.cpp: (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases):
  • VM/Machine.cpp: (JSC::Machine::privateExecute): (JSC::Machine::cti_op_eq): (JSC::Machine::cti_op_neq):
  • kjs/operations.cpp: (JSC::equal): (JSC::equalSlowCase):
  • kjs/operations.h: (JSC::equalSlowCaseInline):
  • Property svn:eol-style set to native
File size: 4.7 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2000 Harri Porten ([email protected])
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef _KJS_OPERATIONS_H_
23#define _KJS_OPERATIONS_H_
24
25#include "JSImmediate.h"
26#include "JSNumberCell.h"
27#include "JSString.h"
28
29namespace JSC {
30
31 class ExecState;
32 class JSValue;
33
34 // ECMA 11.9.3
35 bool equal(ExecState*, JSValue*, JSValue*);
36 bool equalSlowCase(ExecState*, JSValue*, JSValue*);
37
38 ALWAYS_INLINE bool equalSlowCaseInline(ExecState* exec, JSValue* v1, JSValue* v2)
39 {
40 ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2));
41
42 do {
43 if (v1->isNumber() && v2->isNumber())
44 return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();
45
46 bool s1 = v1->isString();
47 bool s2 = v2->isString();
48 if (s1 && s2)
49 return static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
50
51 if (v1->isUndefinedOrNull()) {
52 if (v2->isUndefinedOrNull())
53 return true;
54 if (JSImmediate::isImmediate(v2))
55 return false;
56 return v2->asCell()->structureID()->typeInfo().masqueradesAsUndefined();
57 }
58
59 if (v2->isUndefinedOrNull()) {
60 if (JSImmediate::isImmediate(v1))
61 return false;
62 return v1->asCell()->structureID()->typeInfo().masqueradesAsUndefined();
63 }
64
65 if (v1->isObject()) {
66 if (v2->isObject())
67 return v1 == v2;
68 JSValue* p1 = v1->toPrimitive(exec);
69 if (exec->hadException())
70 return false;
71 v1 = p1;
72 if (JSImmediate::areBothImmediateNumbers(v1, v2))
73 return v1 == v2;
74 continue;
75 }
76
77 if (v2->isObject()) {
78 JSValue* p2 = v2->toPrimitive(exec);
79 if (exec->hadException())
80 return false;
81 v2 = p2;
82 if (JSImmediate::areBothImmediateNumbers(v1, v2))
83 return v1 == v2;
84 continue;
85 }
86
87 if (s1 || s2) {
88 double d1 = v1->toNumber(exec);
89 double d2 = v2->toNumber(exec);
90 return d1 == d2;
91 }
92
93 if (v1->isBoolean()) {
94 if (v2->isNumber())
95 return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber();
96 } else if (v2->isBoolean()) {
97 if (v1->isNumber())
98 return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean());
99 }
100
101 return v1 == v2;
102 } while (true);
103 }
104
105
106 bool strictEqual(JSValue*, JSValue*);
107 bool strictEqualSlowCase(JSValue*, JSValue*);
108
109 inline bool strictEqualSlowCaseInline(JSValue* v1, JSValue* v2)
110 {
111 ASSERT(!JSImmediate::areBothImmediate(v1, v2));
112
113 if (JSImmediate::isEitherImmediate(v1, v2)) {
114 ASSERT(v1 == JSImmediate::zeroImmediate() || v2 == JSImmediate::zeroImmediate());
115 ASSERT(v1 != v2);
116
117 // The reason we can't just return false here is that 0 === -0,
118 // and while the former is an immediate number, the latter is not.
119 if (v1 == JSImmediate::zeroImmediate())
120 return static_cast<JSCell*>(v2)->isNumber() && static_cast<JSNumberCell*>(v2)->value() == 0;
121 return static_cast<JSCell*>(v1)->isNumber() && static_cast<JSNumberCell*>(v1)->value() == 0;
122 }
123
124 if (static_cast<JSCell*>(v1)->isNumber()) {
125 return static_cast<JSCell*>(v2)->isNumber()
126 && static_cast<JSNumberCell*>(v1)->value() == static_cast<JSNumberCell*>(v2)->value();
127 }
128
129 if (static_cast<JSCell*>(v1)->isString()) {
130 return static_cast<JSCell*>(v2)->isString()
131 && static_cast<JSString*>(v1)->value() == static_cast<JSString*>(v2)->value();
132 }
133
134 return v1 == v2;
135 }
136
137 JSValue* throwOutOfMemoryError(ExecState*);
138}
139
140#endif
Note: See TracBrowser for help on using the repository browser.