source: webkit/trunk/JavaScriptCore/kjs/value.cpp@ 12728

Last change on this file since 12728 was 12728, checked in by ggaren, 19 years ago

Reviewed by mjs.

  • Fixed <rdar://problem/4343730> Should switch ConstantValues (null, undefined, true, false) from JS objects to immediate values similar to SimpleNumber

2.0% performance gain on my new super-accurate version of JS iBench.
(I promise to land a version of it soon.)

The gist of the change:
(1) The SimpleNumber class (simple_number.h) is now the JSImmediate
class (JSImmediate.h/.cpp), and it handles not only numbers but also
null, undefined, true, and false.
(2) JSImmediate provides convenience methods for the bit masking
necessary to encode and decode immediate values.
(3) ConstantValues, BooleanImp, NullImp, and UndefinedImp are gone.
(4) JSCell no longer implements functions like getBoolean, because
only a JSImmediate can be a boolean.
(5) JSImmediate no longer uses ALWAYS_INLINE because there's no need,
and ALWAYS_INLINE is a non-portable option of last resort.
(6) Type is now JSType, and it resides in its own file, JSType.h.
Since I was there, I did some header include sorting as part of this
change.

The rest pretty much explains itself.

  • JavaScriptCore.xcodeproj/project.pbxproj: Removed simple_number.h, added JSImmediate.h/.cpp.
  • bindings/c/c_instance.cpp: (KJS::Bindings::CInstance::defaultValue):
  • bindings/c/c_instance.h:
  • bindings/c/c_utility.cpp: (KJS::Bindings::convertValueToNPVariant):
  • bindings/jni/jni_instance.cpp: (JavaInstance::defaultValue):
  • bindings/jni/jni_instance.h:
  • bindings/jni/jni_jsobject.cpp: (JavaJSObject::convertValueToJObject):
  • bindings/objc/WebScriptObject.mm: (+[WebScriptObject _convertValueToObjcValue:originExecutionContext:executionContext:]): Standardized calls to use getXXX instead of hand-rolling JSValue functionality.
  • bindings/objc/objc_instance.h:
  • bindings/objc/objc_instance.mm: (ObjcInstance::getValueOfUndefinedField): (ObjcInstance::defaultValue):
  • bindings/objc/objc_runtime.h:
  • bindings/objc/objc_runtime.mm: (ObjcFallbackObjectImp::type): (ObjcFallbackObjectImp::defaultValue):
  • bindings/runtime.h: (KJS::Bindings::Instance::getValueOfUndefinedField):
  • bindings/runtime_object.cpp: (RuntimeObjectImp::defaultValue):
  • bindings/runtime_object.h:
  • kjs/JSImmediate.h: Added. (KJS::JSImmediate::isImmediate): (KJS::JSImmediate::isNumber): (KJS::JSImmediate::isBoolean): (KJS::JSImmediate::isUndefinedOrNull): (KJS::JSImmediate::fromDouble): (KJS::JSImmediate::toDouble): (KJS::JSImmediate::toBoolean): (KJS::JSImmediate::trueImmediate): (KJS::JSImmediate::falseImmediate): (KJS::JSImmediate::NaNImmediate): (KJS::JSImmediate::undefinedImmediate): (KJS::JSImmediate::nullImmediate): (KJS::JSImmediate::tag): (KJS::JSImmediate::unTag): (KJS::JSImmediate::getTag): (KJS::JSImmediate::): (KJS::JSImmediate::isIEEE): (KJS::JSImmediate::is32bit): (KJS::JSImmediate::is64bit): (KJS::JSImmediate::NanAsBits): (KJS::JSImmediate::zeroAsBits): (KJS::JSImmediate::oneAsBits):
  • kjs/JSLock.cpp: (KJS::JSLock::lock): Removed hack-o-rama to initialize ConstantValues.
  • kjs/JSType.h: Added.
  • kjs/collector.cpp: (KJS::Collector::protect): (KJS::Collector::unprotect): (KJS::Collector::collect):
  • kjs/internal.cpp: (KJS::StringImp::toPrimitive): (KJS::NumberImp::toPrimitive): (KJS::NumberImp::toBoolean): (KJS::GetterSetterImp::toPrimitive):
  • kjs/internal.h: (KJS::StringImp::type): (KJS::NumberImp::type):
  • kjs/object.cpp: (KJS::JSObject::type): (KJS::tryGetAndCallProperty): Replaced "Are you one of the six things I'm looking for?" test with "Are you not the one thing I'm not looking for" test. (KJS::JSObject::defaultValue): (KJS::JSObject::toPrimitive):
  • kjs/object.h: (KJS::GetterSetterImp::type): (KJS::JSValue::isObject):
  • kjs/operations.cpp: (KJS::equal): (KJS::strictEqual): (KJS::add):
  • kjs/reference.cpp: (KJS::Reference::deleteValue):
  • kjs/simple_number.h: Removed.
  • kjs/string_object.cpp: (StringInstance::getOwnPropertySlot): fixed indentation
  • kjs/value.cpp: (KJS::JSValue::toObject): (KJS::jsNumberCell): New function to quarantine a PIC branch -- allows us to inline jsNumber without adding PIC branches to callers.
  • kjs/value.h: (KJS::jsUndefined): (KJS::jsNull): (KJS::jsNaN): (KJS::jsBoolean): (KJS::jsNumber): (KJS::JSValue::downcast): (KJS::JSValue::isUndefinedOrNull): (KJS::JSValue::isBoolean): (KJS::JSValue::isNumber): (KJS::JSValue::isString): (KJS::JSValue::isObject): (KJS::JSValue::getBoolean): (KJS::JSValue::getNumber): (KJS::JSValue::getString): (KJS::JSValue::getObject): (KJS::JSValue::getUInt32): (KJS::JSValue::mark): Replaced !JSImmediate::is() test with assertion, resulting in a slight performance gain. Callers should always check !marked() before calling mark(), so it's impossible to call mark on a JSImmediate. (KJS::JSValue::marked): (KJS::JSValue::type): (KJS::JSValue::toPrimitive): (KJS::JSValue::toBoolean): (KJS::JSValue::toNumber): (KJS::JSValue::toString):
  • Property svn:eol-style set to native
File size: 4.0 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2001 Harri Porten ([email protected])
4 * Copyright (C) 2001 Peter Kelly ([email protected])
5 * Copyright (C) 2003 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25#include "value.h"
26
27#include "object.h"
28#include "types.h"
29#include "interpreter.h"
30
31#include <math.h>
32#include <stdio.h>
33#include <string.h>
34
35#include "internal.h"
36#include "collector.h"
37#include "operations.h"
38#include "error_object.h"
39#include "nodes.h"
40
41namespace KJS {
42
43static const double D16 = 65536.0;
44static const double D32 = 4294967296.0;
45
46void *JSCell::operator new(size_t size)
47{
48 return Collector::allocate(size);
49}
50
51bool JSCell::getUInt32(unsigned&) const
52{
53 return false;
54}
55
56// ECMA 9.4
57double JSValue::toInteger(ExecState *exec) const
58{
59 uint32_t i;
60 if (getUInt32(i))
61 return i;
62 return roundValue(exec, const_cast<JSValue*>(this));
63}
64
65int32_t JSValue::toInt32(ExecState *exec) const
66{
67 uint32_t i;
68 if (getUInt32(i))
69 return i;
70
71 double d = roundValue(exec, const_cast<JSValue*>(this));
72 if (isNaN(d) || isInf(d))
73 return 0;
74 double d32 = fmod(d, D32);
75
76 if (d32 >= D32 / 2)
77 d32 -= D32;
78 else if (d32 < -D32 / 2)
79 d32 += D32;
80
81 return static_cast<int32_t>(d32);
82}
83
84uint32_t JSValue::toUInt32(ExecState *exec) const
85{
86 uint32_t i;
87 if (getUInt32(i))
88 return i;
89
90 double d = roundValue(exec, const_cast<JSValue*>(this));
91 if (isNaN(d) || isInf(d))
92 return 0;
93 double d32 = fmod(d, D32);
94
95 if (d32 < 0)
96 d32 += D32;
97
98 return static_cast<uint32_t>(d32);
99}
100
101uint16_t JSValue::toUInt16(ExecState *exec) const
102{
103 uint32_t i;
104 if (getUInt32(i))
105 return i;
106
107 double d = roundValue(exec, const_cast<JSValue*>(this));
108 if (isNaN(d) || isInf(d))
109 return 0;
110 double d16 = fmod(d, D16);
111
112 if (d16 < 0)
113 d16 += D16;
114
115 return static_cast<uint16_t>(d16);
116}
117
118JSObject *JSValue::toObject(ExecState *exec) const
119{
120 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : downcast()->toObject(exec);
121}
122
123bool JSCell::getNumber(double &numericValue) const
124{
125 if (!isNumber())
126 return false;
127 numericValue = static_cast<const NumberImp *>(this)->value();
128 return true;
129}
130
131double JSCell::getNumber() const
132{
133 return isNumber() ? static_cast<const NumberImp *>(this)->value() : NaN;
134}
135
136bool JSCell::getString(UString &stringValue) const
137{
138 if (!isString())
139 return false;
140 stringValue = static_cast<const StringImp *>(this)->value();
141 return true;
142}
143
144UString JSCell::getString() const
145{
146 return isString() ? static_cast<const StringImp *>(this)->value() : UString();
147}
148
149JSObject *JSCell::getObject()
150{
151 return isObject() ? static_cast<JSObject *>(this) : 0;
152}
153
154const JSObject *JSCell::getObject() const
155{
156 return isObject() ? static_cast<const JSObject *>(this) : 0;
157}
158
159JSCell *jsString(const char *s)
160{
161 return new StringImp(s ? s : "");
162}
163
164JSCell *jsString(const UString &s)
165{
166 return s.isNull() ? new StringImp("") : new StringImp(s);
167}
168
169// This method includes a PIC branch to set up the NumberImp's vtable, so we quarantine
170// it in a separate function to keep the normal case speedy.
171JSValue *jsNumberCell(double d)
172{
173 return new NumberImp(d);
174}
175
176} // namespace KJS
Note: See TracBrowser for help on using the repository browser.