JavaScriptCore:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Aug 2006 03:06:14 +0000 (03:06 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Aug 2006 03:06:14 +0000 (03:06 +0000)
        Reviewed (and tweaked a little) by Maciej.

        - shrank the size of JSObject by 8 bytes and made the corresponding reduction to the cell size, resulting
        in a 1.2% speed improvement on JS iBench (and probably overall memory savings).

        This was done by removing _scope and _internalValue data members
        from JSObject and moving them only to the subclasses that actually
        make use of them.

        * kjs/object.cpp:
        (KJS::JSObject::mark): No need to mark scope or internal value here.
        * kjs/object.h:
        (KJS::JSObject::JSObject): Don't initialize them.
        * kjs/JSWrapperObject.cpp: Added. New base class for object types that
        wrap primitive values (Number, String, Boolean, Date).
        (KJS::JSWrapperObject::mark):
        * kjs/JSWrapperObject.h: Added.
        (KJS::JSWrapperObject::JSWrapperObject):
        (KJS::JSWrapperObject::internalValue):
        (KJS::JSWrapperObject::setInternalValue):
        * kjs/array_object.cpp:
        (ArrayPrototype::ArrayPrototype): Don't set useless internal value.
        * kjs/bool_object.cpp:
        (BooleanInstance::BooleanInstance): Inherit from JSWrapperObject.
        (BooleanProtoFunc::callAsFunction): Fixed to account for fact that not all
        JSObjects have an internal value.
        (BooleanObjectImp::construct): ditto.
        * kjs/bool_object.h:
        * kjs/collector.cpp: Lowered cell size to 48.
        (KJS::Collector::allocate): meaningless whitespace change
        * kjs/date_object.cpp:
        (KJS::DateInstance::DateInstance): Inherit from JSWrapperObject.
        (KJS::DateProtoFunc::callAsFunction): adjusted for move of internalValue
        (KJS::DateObjectImp::construct): ditto
        * kjs/date_object.h:
        * kjs/error_object.cpp:
        (ErrorPrototype::ErrorPrototype): don't set internal value
        * kjs/function.cpp: move _scope and related handling here
        (KJS::FunctionImp::mark): mark scope
        * kjs/function.h:
        (KJS::FunctionImp::scope): moved here from JSObject
        (KJS::FunctionImp::setScope): ditto
        * kjs/number_object.cpp:
        (NumberInstance::NumberInstance): inherit from JSWrapperObject
        (NumberProtoFunc::callAsFunction): adjusted
        (NumberObjectImp::construct): adjusted
        * kjs/number_object.h: shring RegExp-related objects a little
        * kjs/regexp_object.cpp:
        (RegExpPrototype::RegExpPrototype): Adjust for size tweaks
        (RegExpObjectImp::RegExpObjectImp): ditto
        * kjs/regexp_object.h:
        * kjs/string_object.cpp:
        (StringInstance::StringInstance): inherit from JSWrapperObject
        (StringProtoFunc::callAsFunction): adjusted
        * kjs/string_object.h:
        * JavaScriptCore.exp: Exported new methods as needed.
        * JavaScriptCore.xcodeproj/project.pbxproj: Added new files to build.

WebCore:

        Reviewed (and tweaked a little) by Maciej.

        - shrank the size of JSObject by 8 bytes and made the corresponding reduction to the cell size, resulting
        in a 1.2% speed improvement on JS iBench (and probably overall memory savings).

        The WebCore part of this is to expect only FunctionImp to have a scope, not all JSObjects.

        * bindings/js/kjs_events.cpp:
        (KJS::JSLazyEventListener::parseCode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15846 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/kjs/JSWrapperObject.cpp [new file with mode: 0644]
JavaScriptCore/kjs/JSWrapperObject.h [new file with mode: 0644]
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/bool_object.cpp
JavaScriptCore/kjs/bool_object.h
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/date_object.h
JavaScriptCore/kjs/error_object.cpp
JavaScriptCore/kjs/function.cpp
JavaScriptCore/kjs/function.h
JavaScriptCore/kjs/number_object.cpp
JavaScriptCore/kjs/number_object.h
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/regexp_object.cpp
JavaScriptCore/kjs/regexp_object.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
WebCore/ChangeLog
WebCore/bindings/js/kjs_events.cpp
WebCore/bindings/objc/WebScriptObjectInternal.h [new file with mode: 0644]

index e28587c7cbbe23d32792e18896cc86dbd6f9dfdf..d71997fef8d997f82d2d4742aeab83afc95218bb 100644 (file)
@@ -1,3 +1,63 @@
+2006-08-13  Maks Orlovich  <maksim@kde.org>
+
+        Reviewed (and tweaked a little) by Maciej.
+        
+        - shrank the size of JSObject by 8 bytes and made the corresponding reduction to the cell size, resulting
+        in a 1.2% speed improvement on JS iBench (and probably overall memory savings).
+
+        This was done by removing _scope and _internalValue data members
+        from JSObject and moving them only to the subclasses that actually
+        make use of them.
+        
+        * kjs/object.cpp: 
+        (KJS::JSObject::mark): No need to mark scope or internal value here.
+        * kjs/object.h:
+        (KJS::JSObject::JSObject): Don't initialize them.
+        * kjs/JSWrapperObject.cpp: Added. New base class for object types that
+        wrap primitive values (Number, String, Boolean, Date).
+        (KJS::JSWrapperObject::mark): 
+        * kjs/JSWrapperObject.h: Added.
+        (KJS::JSWrapperObject::JSWrapperObject):
+        (KJS::JSWrapperObject::internalValue):
+        (KJS::JSWrapperObject::setInternalValue):
+        * kjs/array_object.cpp:
+        (ArrayPrototype::ArrayPrototype): Don't set useless internal value.
+        * kjs/bool_object.cpp:
+        (BooleanInstance::BooleanInstance): Inherit from JSWrapperObject.
+        (BooleanProtoFunc::callAsFunction): Fixed to account for fact that not all
+        JSObjects have an internal value.
+        (BooleanObjectImp::construct): ditto.
+        * kjs/bool_object.h:
+        * kjs/collector.cpp: Lowered cell size to 48.
+        (KJS::Collector::allocate): meaningless whitespace change
+        * kjs/date_object.cpp:
+        (KJS::DateInstance::DateInstance): Inherit from JSWrapperObject.
+        (KJS::DateProtoFunc::callAsFunction): adjusted for move of internalValue
+        (KJS::DateObjectImp::construct): ditto
+        * kjs/date_object.h:
+        * kjs/error_object.cpp:
+        (ErrorPrototype::ErrorPrototype): don't set internal value
+        * kjs/function.cpp: move _scope and related handling here
+        (KJS::FunctionImp::mark): mark scope
+        * kjs/function.h:
+        (KJS::FunctionImp::scope): moved here from JSObject
+        (KJS::FunctionImp::setScope): ditto
+        * kjs/number_object.cpp:
+        (NumberInstance::NumberInstance): inherit from JSWrapperObject
+        (NumberProtoFunc::callAsFunction): adjusted
+        (NumberObjectImp::construct): adjusted
+        * kjs/number_object.h: shring RegExp-related objects a little
+        * kjs/regexp_object.cpp:
+        (RegExpPrototype::RegExpPrototype): Adjust for size tweaks
+        (RegExpObjectImp::RegExpObjectImp): ditto
+        * kjs/regexp_object.h:
+        * kjs/string_object.cpp:
+        (StringInstance::StringInstance): inherit from JSWrapperObject
+        (StringProtoFunc::callAsFunction): adjusted
+        * kjs/string_object.h:
+        * JavaScriptCore.exp: Exported new methods as needed.
+        * JavaScriptCore.xcodeproj/project.pbxproj: Added new files to build.
+
 2006-08-04  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Geoff's rubber stamp
index 72b7470eeb60c2673e2132eafa6a11f359a2ce11..11184a47b787a8650dc595a239e48e54339ba3eb 100644 (file)
@@ -1,4 +1,3 @@
-
 _JSCheckScriptSyntax
 _JSClassCreate
 _JSClassRelease
@@ -151,6 +150,7 @@ __ZN3KJS14StringInstance3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
 __ZN3KJS14StringInstance4infoE
 __ZN3KJS14StringInstanceC1EPNS_8JSObjectERKNS_7UStringE
 __ZN3KJS14StringInstanceC2EPNS_8JSObjectERKNS_7UStringE
+__ZN3KJS15JSWrapperObject4markEv
 __ZN3KJS15SavedPropertiesC1Ev
 __ZN3KJS15SavedPropertiesD1Ev
 __ZN3KJS16RuntimeObjectImp4infoE
@@ -269,6 +269,7 @@ __ZNK3KJS8JSObject9classNameEv
 __ZNK3KJS8JSObject9toBooleanEPNS_9ExecStateE
 __ZNK3KJS9ExecState18lexicalInterpreterEv
 __ZTVN3KJS14StringInstanceE
+__ZTVN3KJS15JSWrapperObjectE
 __ZTVN3KJS19InternalFunctionImpE
 __ZTVN3KJS8JSObjectE
 _kJSClassDefinitionEmpty
index 2bab9faea5579c97c2d037bd9bb9c3f4227c2e5c..c2130168a8d0d2584432e0a17c92d47b2f430f70 100644 (file)
@@ -95,6 +95,8 @@
                65B174F609D100FA00820339 /* number_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B174F209D100FA00820339 /* number_object.lut.h */; };
                65B174F809D100FA00820339 /* string_object.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B174F409D100FA00820339 /* string_object.lut.h */; };
                65C647B4093EF8D60022C380 /* RefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C647B3093EF8D60022C380 /* RefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               65C7A1730A8EAACB00FA37EA /* JSWrapperObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */; };
+               65C7A1740A8EAACB00FA37EA /* JSWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65D6D87F09B5A32E0002E4D7 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D6D87E09B5A32E0002E4D7 /* Platform.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */; };
                65DFC93008EA173A00F7300B /* HashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92A08EA173A00F7300B /* HashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65B174F409D100FA00820339 /* string_object.lut.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = string_object.lut.h; sourceTree = "<group>"; };
                65C02FBB0637462A003E7EE6 /* protect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = protect.h; sourceTree = "<group>"; tabWidth = 8; };
                65C647B3093EF8D60022C380 /* RefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RefPtr.h; sourceTree = "<group>"; tabWidth = 8; };
+               65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; };
+               65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; };
                65D6D87E09B5A32E0002E4D7 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
                65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = FastMallocInternal.h; sourceTree = "<group>"; tabWidth = 8; };
                65DFC92A08EA173A00F7300B /* HashFunctions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashFunctions.h; sourceTree = "<group>"; tabWidth = 8; };
                65417200039E01BA0058BFEB /* kjs */ = {
                        isa = PBXGroup;
                        children = (
+                               65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */,
+                               65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */,
                                65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */,
                                65400C100A69BAF200509887 /* PropertyNameArray.h */,
                                938772E5038BFE19008635CE /* array_instance.h */,
                                1440FCE30A51E46B0005F061 /* JSClassRef.h in Headers */,
                                65400C120A69BAF200509887 /* PropertyNameArray.h in Headers */,
                                1CAF34890A6C421700ABE06E /* WebScriptObject.h in Headers */,
+                               65C7A1740A8EAACB00FA37EA /* JSWrapperObject.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
                                1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
                                65400C110A69BAF200509887 /* PropertyNameArray.cpp in Sources */,
+                               65C7A1730A8EAACB00FA37EA /* JSWrapperObject.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/JavaScriptCore/kjs/JSWrapperObject.cpp b/JavaScriptCore/kjs/JSWrapperObject.cpp
new file mode 100644 (file)
index 0000000..dd161f7
--- /dev/null
@@ -0,0 +1,34 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ *  Copyright (C) 2006 Maks Orlovich
+ *  Copyright (C) 2006 Apple Computer, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "JSWrapperObject.h"
+
+namespace KJS {
+
+void JSWrapperObject::mark() 
+{
+    JSObject::mark();
+    if (m_internalValue && !m_internalValue->marked())
+        m_internalValue->mark();
+}
+
+} // namespace KJS
diff --git a/JavaScriptCore/kjs/JSWrapperObject.h b/JavaScriptCore/kjs/JSWrapperObject.h
new file mode 100644 (file)
index 0000000..0a06c9f
--- /dev/null
@@ -0,0 +1,84 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ *  Copyright (C) 2006 Maks Orlovich
+ *  Copyright (C) 2006 Apple Computer, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KJS_JSWrapperObject_h
+#define KJS_JSWrapperObject_h
+
+#include "object.h"
+
+namespace KJS {
+    
+    /** 
+        This class is used as a base for classes such as String,
+        Number, Boolean and Date which which are wrappers for primitive
+       types. These classes stores the internal value, which is the
+       actual value represented by the wrapper objects.
+    */ 
+    class JSWrapperObject : public JSObject {
+    public:
+        JSWrapperObject(JSValue* proto);
+        
+        /**
+         * Returns the internal value of the object. This is used for objects such
+         * as String and Boolean which are wrappers for native types. The interal
+         * value is the actual value represented by the wrapper objects.
+         *
+         * @see ECMA 8.6.2
+         * @return The internal value of the object
+         */
+        JSValue* internalValue() const;
+        
+        /**
+         * Sets the internal value of the object
+         *
+         * @see internalValue()
+         *
+         * @param v The new internal value
+         */
+        void setInternalValue(JSValue* v);
+        
+        virtual void mark();
+        
+    private:
+        JSValue* m_internalValue;
+    };
+    
+    inline JSWrapperObject::JSWrapperObject(JSValue* proto)
+        : JSObject(proto)
+        , m_internalValue(0)
+    {
+    }
+    
+    inline JSValue* JSWrapperObject::internalValue() const
+    {
+        return m_internalValue;
+    }
+    
+    inline void JSWrapperObject::setInternalValue(JSValue* v)
+    {
+        ASSERT(v);
+        m_internalValue = v;
+    }
+
+} // namespace KJS
+
+#endif // KJS_JSWrapperObject_h
index 80340980fe0899debf0868c6142fa14a150f1148..7ae49ebc7f60459fd023e0ee30ea8917082b226a 100644 (file)
@@ -412,7 +412,6 @@ const ClassInfo ArrayPrototype::info = {"Array", &ArrayInstance::info, &arrayTab
 ArrayPrototype::ArrayPrototype(ExecState*, ObjectPrototype* objProto)
   : ArrayInstance(objProto, 0)
 {
-  setInternalValue(jsNull());
 }
 
 bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
index 0d4229a627e18873fa8c6d12d564ad5af6ac3106..257f6675fbd4dfd409dd2700d890d07040f7e4f6 100644 (file)
@@ -33,7 +33,7 @@ using namespace KJS;
 const ClassInfo BooleanInstance::info = {"Boolean", 0, 0, 0};
 
 BooleanInstance::BooleanInstance(JSObject *proto)
-  : JSObject(proto)
+  : JSWrapperObject(proto)
 {
 }
 
@@ -71,7 +71,7 @@ JSValue *BooleanProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, co
 
   // execute "toString()" or "valueOf()", respectively
 
-  JSValue *v = thisObj->internalValue();
+  JSValue *v = static_cast<BooleanInstance*>(thisObj)->internalValue();
   assert(v);
 
   if (id == ToString)
@@ -100,7 +100,7 @@ bool BooleanObjectImp::implementsConstruct() const
 // ECMA 15.6.2
 JSObject *BooleanObjectImp::construct(ExecState *exec, const List &args)
 {
-  JSObject *obj(new BooleanInstance(exec->lexicalInterpreter()->builtinBooleanPrototype()));
+  BooleanInstance *obj(new BooleanInstance(exec->lexicalInterpreter()->builtinBooleanPrototype()));
 
   bool b;
   if (args.size() > 0)
index d8583236929c76cf963a086920907c88ee4ab612..3ab04a76f7e7d866a5778758fa8b1d4d0d08b895 100644 (file)
 #define BOOL_OBJECT_H_
 
 #include "function_object.h"
+#include "JSWrapperObject.h"
 
 namespace KJS {
 
-  class BooleanInstance : public JSObject {
+  class BooleanInstance : public JSWrapperObject {
   public:
     BooleanInstance(JSObject *proto);
 
index 5d9d89b38dca41f5695a77f18cd3601d9bafdfaa..5ba3b6284d97469f36054594af300783deb01fc8 100644 (file)
@@ -60,7 +60,7 @@ using std::max;
 namespace KJS {
 
 // tunable parameters
-const size_t MINIMUM_CELL_SIZE = 56;
+const size_t MINIMUM_CELL_SIZE = 48;
 const size_t BLOCK_SIZE = (8 * 4096);
 const size_t SPARE_EMPTY_BLOCKS = 2;
 const size_t MIN_ARRAY_SIZE = 14;
@@ -123,7 +123,6 @@ void* Collector::allocate(size_t s)
   
   if (s > CELL_SIZE) {
     // oversize allocator
-
     size_t usedOversizeCells = heap.usedOversizeCells;
     size_t numOversizeCells = heap.numOversizeCells;
 
index 08f3bb322c36f912aae37ff40f456d83ca7310e9..28d39466fb63e81562262a46ee04b8ba094383a8 100644 (file)
@@ -362,7 +362,7 @@ static void fillStructuresUsingDateArgs(ExecState *exec, const List &args, int m
 const ClassInfo DateInstance::info = {"Date", 0, 0, 0};
 
 DateInstance::DateInstance(JSObject *proto)
-  : JSObject(proto)
+  : JSWrapperObject(proto)
 {
 }
 
@@ -534,6 +534,8 @@ JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const
   if (!thisObj->inherits(&DateInstance::info))
     return throwError(exec, TypeError);
 
+  DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
+
   JSValue *result = 0;
   UString s;
 #if !PLATFORM(DARWIN)
@@ -544,7 +546,7 @@ JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const
     oldlocale = setlocale(LC_ALL, 0);
   // FIXME: Where's the code to set the locale back to oldlocale?
 #endif
-  JSValue *v = thisObj->internalValue();
+  JSValue *v = thisDateObj->internalValue();
   double milli = v->toNumber(exec);
   if (isNaN(milli)) {
     switch (id) {
@@ -645,7 +647,7 @@ JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const
   case SetTime:
     milli = roundValue(exec, args[0]);
     result = jsNumber(milli);
-    thisObj->setInternalValue(result);
+    thisDateObj->setInternalValue(result);
     break;
   case SetMilliSeconds:
     fillStructuresUsingTimeArgs(exec, args, 1, &ms, &t);
@@ -677,7 +679,7 @@ JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const
       id == SetMinutes || id == SetHours || id == SetDate ||
       id == SetMonth || id == SetFullYear ) {
     result = jsNumber(makeTime(&t, ms, utc));
-    thisObj->setInternalValue(result);
+    thisDateObj->setInternalValue(result);
   }
   
   return result;
@@ -734,7 +736,7 @@ JSObject *DateObjectImp::construct(ExecState *exec, const List &args)
     value = utc;
   } else if (numArgs == 1) {
     if (args[0]->isObject(&DateInstance::info))
-      value = static_cast<JSObject*>(args[0])->internalValue()->toNumber(exec);
+      value = static_cast<DateInstance*>(args[0])->internalValue()->toNumber(exec);
     else {
       JSValue* primitive = args[0]->toPrimitive(exec);
       if (primitive->isString())
index 3c8847bdd4e8dd3e20e521cc45e08fbb7de4c088..9f44e78cdd563510f952aaaac0cb4e5d285c72cd 100644 (file)
 #define DATE_OBJECT_H
 
 #include "internal.h"
+#include "JSWrapperObject.h"
 
 namespace KJS {
 
     class FunctionPrototype;
     class ObjectPrototype;
 
-    class DateInstance : public JSObject {
+    class DateInstance : public JSWrapperObject {
     public:
         DateInstance(JSObject *proto);
         
index 08ea36b24000369077a39cc96b712635b8973284..f3c0c0aed7aa7021753b0279a65445c42d708fce 100644 (file)
@@ -48,7 +48,6 @@ ErrorPrototype::ErrorPrototype(ExecState *exec,
                                      FunctionPrototype *funcProto)
   : JSObject(objectProto)
 {
-  setInternalValue(jsUndefined());
   // The constructor will be added later in ErrorObjectImp's constructor
 
   put(exec, namePropertyName,     jsString("Error"), DontEnum);
index a5d79653675002a1a03dff8ebd89e5067e56bfcd..20a4be945d70fda8d01382d8420c18e4f9f54d36 100644 (file)
@@ -62,6 +62,12 @@ FunctionImp::FunctionImp(ExecState *exec, const Identifier &n, FunctionBodyNode*
 {
 }
 
+void FunctionImp::mark()
+{
+    InternalFunctionImp::mark();
+    _scope.mark();
+}
+
 FunctionImp::~FunctionImp()
 {
 }
index 79cd44bd322eab02e2369f5f377f11b4fb877d22..72674b83c5e93f5c15fdd71a5126c486be0ff0af 100644 (file)
@@ -61,10 +61,42 @@ namespace KJS {
 
     RefPtr<FunctionBodyNode> body;
 
+    /**
+     * Returns the scope of this object. This is used when execution declared
+     * functions - the execution context for the function is initialized with
+     * extra object in it's scope. An example of this is functions declared
+     * inside other functions:
+     *
+     * \code
+     * function f() {
+     *
+     *   function b() {
+     *     return prototype;
+     *   }
+     *
+     *   var x = 4;
+     *   // do some stuff
+     * }
+     * f.prototype = new String();
+     * \endcode
+     *
+     * When the function f.b is executed, its scope will include properties of
+     * f. So in the example above the return value of f.b() would be the new
+     * String object that was assigned to f.prototype.
+     *
+     * @param exec The current execution state
+     * @return The function's scope
+     */
+    const ScopeChain &scope() const { return _scope; }
+    void setScope(const ScopeChain &s) { _scope = s; }
+
+    virtual void mark();
   protected:
     OwnPtr<Parameter> param;
 
   private:
+    ScopeChain _scope;
+
     static JSValue *argumentsGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot&);
     static JSValue *lengthGetter(ExecState *, JSObject *, const Identifier &, const PropertySlot&);
 
index dce5227bf76842d19e85ea4f6c5dcb0d486beeb3..5ea191c68132dbb0e96682ed949b78da035e2bd6 100644 (file)
@@ -36,7 +36,7 @@ using namespace KJS;
 const ClassInfo NumberInstance::info = {"Number", 0, 0, 0};
 
 NumberInstance::NumberInstance(JSObject *proto)
-  : JSObject(proto)
+  : JSWrapperObject(proto)
 {
 }
 // ------------------------------ NumberPrototype ---------------------------
@@ -147,7 +147,7 @@ JSValue *NumberProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, con
   if (!thisObj->inherits(&NumberInstance::info))
     return throwError(exec, TypeError);
 
-  JSValue *v = thisObj->internalValue();
+  JSValue *v = static_cast<NumberInstance*>(thisObj)->internalValue();
   switch (id) {
   case ToString: {
     double dradix = 10;
@@ -460,7 +460,7 @@ bool NumberObjectImp::implementsConstruct() const
 JSObject *NumberObjectImp::construct(ExecState *exec, const List &args)
 {
   JSObject *proto = exec->lexicalInterpreter()->builtinNumberPrototype();
-  JSObject *obj(new NumberInstance(proto));
+  NumberInstance *obj(new NumberInstance(proto));
 
   double n;
   if (args.isEmpty())
index 56a672ab62f52bbb9a85145dec500969ded062f8..8a3e39c9c3e6d2f8827eb4047000a64c7f7545c1 100644 (file)
 #define NUMBER_OBJECT_H_
 
 #include "function_object.h"
+#include "JSWrapperObject.h"
 
 namespace KJS {
 
-  class NumberInstance : public JSObject {
+  class NumberInstance : public JSWrapperObject {
   public:
     NumberInstance(JSObject *proto);
 
index a28fc269516282e386954c1eaa8e29ca1ff60e9f..74c1e12dc159f2f7ff4fb7c2e4fb72a96c67bf4f 100644 (file)
@@ -123,11 +123,6 @@ void JSObject::mark()
     proto->mark();
 
   _prop.mark();
-
-  if (_internalValue && !_internalValue->marked())
-    _internalValue->mark();
-
-  _scope.mark();
 }
 
 JSType JSObject::type() const
index 6a05fa74e6c39c61962b1f2715f222e479bc07ae..adceed6467dcbcfff95c5de3487933d870dec997 100644 (file)
@@ -412,56 +412,8 @@ namespace KJS {
      */
     virtual bool hasInstance(ExecState *exec, JSValue *value);
 
-    /**
-     * Returns the scope of this object. This is used when execution declared
-     * functions - the execution context for the function is initialized with
-     * extra object in it's scope. An example of this is functions declared
-     * inside other functions:
-     *
-     * \code
-     * function f() {
-     *
-     *   function b() {
-     *     return prototype;
-     *   }
-     *
-     *   var x = 4;
-     *   // do some stuff
-     * }
-     * f.prototype = new String();
-     * \endcode
-     *
-     * When the function f.b is executed, its scope will include properties of
-     * f. So in the example above the return value of f.b() would be the new
-     * String object that was assigned to f.prototype.
-     *
-     * @param exec The current execution state
-     * @return The function's scope
-     */
-    const ScopeChain &scope() const { return _scope; }
-    void setScope(const ScopeChain &s) { _scope = s; }
-
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
-    /**
-     * Returns the internal value of the object. This is used for objects such
-     * as String and Boolean which are wrappers for native types. The interal
-     * value is the actual value represented by the wrapper objects.
-     *
-     * @see ECMA 8.6.2
-     * @return The internal value of the object
-     */
-    JSValue *internalValue() const;
-
-    /**
-     * Sets the internal value of the object
-     *
-     * @see internalValue()
-     *
-     * @param v The new internal value
-     */
-    void setInternalValue(JSValue *v);
-
     virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
     virtual bool toBoolean(ExecState *exec) const;
     virtual double toNumber(ExecState *exec) const;
@@ -507,8 +459,6 @@ namespace KJS {
   private:
     const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const;
     JSValue *_proto;
-    JSValue *_internalValue;
-    ScopeChain _scope;
   };
 
   /**
@@ -555,7 +505,6 @@ JSObject *throwError(ExecState *, ErrorType);
 inline JSObject::JSObject(JSValue* proto, bool destructorIsThreadSafe)
     : JSCell(destructorIsThreadSafe)
     , _proto(proto)
-    , _internalValue(0)
 {
     assert(proto);
 }
@@ -563,20 +512,9 @@ inline JSObject::JSObject(JSValue* proto, bool destructorIsThreadSafe)
 inline JSObject::JSObject(bool destructorIsThreadSafe)
     : JSCell(destructorIsThreadSafe)
     , _proto(jsNull())
-    , _internalValue(0)
 {
 }
 
-inline JSValue *JSObject::internalValue() const
-{
-    return _internalValue;
-}
-
-inline void JSObject::setInternalValue(JSValue *v)
-{
-    _internalValue = v;
-}
-
 inline JSValue *JSObject::prototype() const
 {
     return _proto;
@@ -647,6 +585,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState *exec, const Identifie
     return false;
 }
 
+
 // FIXME: Put this function in a separate file named something like scope_chain_mark.h -- can't put it in scope_chain.h since it depends on JSObject.
 
 inline void ScopeChain::mark()
index 5a5ace675becde3244f06b6ab4c5fd1dd2355618..0a9ba9a51ece7c039fd2ad44196d3b31158cb17f 100644 (file)
@@ -39,7 +39,7 @@ using namespace KJS;
 
 // ------------------------------ RegExpPrototype ---------------------------
 
-// ECMA 15.9.4
+// ECMA 15.10.5
 
 const ClassInfo RegExpPrototype::info = {"RegExpPrototype", 0, 0, 0};
 
@@ -48,8 +48,6 @@ RegExpPrototype::RegExpPrototype(ExecState *exec,
                                        FunctionPrototype *funcProto)
   : JSObject(objProto)
 {
-  setInternalValue(jsString(""));
-
   // The constructor will be added later in RegExpObject's constructor (?)
 
   static const Identifier execPropertyName("exec");
@@ -185,7 +183,7 @@ const ClassInfo RegExpObjectImp::info = {"Function", &InternalFunctionImp::info,
 
 RegExpObjectImp::RegExpObjectImp(ExecState*, FunctionPrototype* funcProto, RegExpPrototype* regProto)
 
-  : InternalFunctionImp(funcProto), multiline(false), lastInput(""), lastNumSubPatterns(0)
+  : InternalFunctionImp(funcProto), lastInput(""), lastNumSubPatterns(0), multiline(false)
 {
   // ECMA 15.10.5.1 RegExp.prototype
   putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
index 0f23f81b426331b48c9bbd7d1d6fdc4a3fcbdba0..0e58153529ea0768e2d388e3a4ff568d41afab91 100644 (file)
@@ -88,10 +88,10 @@ namespace KJS {
     JSValue *getRightContext() const;
 
     // Global search cache / settings
-    bool multiline;
     UString lastInput;
     OwnArrayPtr<int> lastOvector;
-    unsigned lastNumSubPatterns;
+    unsigned lastNumSubPatterns : 31;
+    bool multiline              : 1;
     
     static const ClassInfo info;
   };
index bb1d0a6c011da7dead151f9ac2cc69a48849ad73..31ec6808fa4a0999356d3f37997cda51b2321ba8 100644 (file)
@@ -24,6 +24,7 @@
 #include "string_object.h"
 #include "string_object.lut.h"
 
+#include "JSWrapperObject.h"
 #include "error_object.h"
 #include "operations.h"
 #include "PropertyNameArray.h"
@@ -37,13 +38,13 @@ using namespace KJS;
 const ClassInfo StringInstance::info = {"String", 0, 0, 0};
 
 StringInstance::StringInstance(JSObject *proto)
-  : JSObject(proto)
+  : JSWrapperObject(proto)
 {
   setInternalValue(jsString(""));
 }
 
 StringInstance::StringInstance(JSObject *proto, const UString &string)
-  : JSObject(proto)
+  : JSWrapperObject(proto)
 {
   setInternalValue(jsString(string));
 }
@@ -390,7 +391,7 @@ JSValue *StringProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, con
     if (!thisObj || !thisObj->inherits(&StringInstance::info))
       return throwError(exec, TypeError);
 
-    return jsString(thisObj->internalValue()->toString(exec));
+    return jsString(static_cast<StringInstance*>(thisObj)->internalValue()->toString(exec));
   }
 
   UString u, u2, u3;
index afa214b009c10c63a14b168fbdc89358eb191820..b3978e091c95a9900418c4d47f8617a598d0a167 100644 (file)
 #define STRING_OBJECT_H_
 
 #include "function_object.h"
+#include "JSWrapperObject.h"
 
 namespace KJS {
 
-  class StringInstance : public JSObject {
+  class StringInstance : public JSWrapperObject {
   public:
     StringInstance(JSObject *proto);
     StringInstance(JSObject *proto, const UString &string);
index f84f040cc3780d355590d456776d7379f10e4e2a..63c07761a6979a20532bc187beb99d6b26aa92f7 100644 (file)
@@ -1,3 +1,15 @@
+2006-08-13  Maks Orlovich  <maksim@kde.org>
+
+        Reviewed (and tweaked a little) by Maciej.
+        
+        - shrank the size of JSObject by 8 bytes and made the corresponding reduction to the cell size, resulting
+        in a 1.2% speed improvement on JS iBench (and probably overall memory savings).
+
+        The WebCore part of this is to expect only FunctionImp to have a scope, not all JSObjects.
+        
+        * bindings/js/kjs_events.cpp:
+        (KJS::JSLazyEventListener::parseCode):
+
 2006-08-12  Eric Seidel  <eric@eseidel.com>
 
         Reviewed by hyatt and mjs.
index c6e027eb7ea201fe0ad411834bf38f0a14474831..ed548b77c2a1e8d9891878e09dddaf83396a9375 100644 (file)
@@ -284,6 +284,8 @@ void JSLazyEventListener::parseCode() const
         args.append(jsString(code));
         listener = constr->construct(exec, args, m_functionName, sourceURL, lineNumber); // ### is globalExec ok ?
 
+        FunctionImp* listenerAsFunction = static_cast<FunctionImp*>(listener.get());
+
         if (exec->hadException()) {
             exec->clearException();
 
@@ -292,12 +294,12 @@ void JSLazyEventListener::parseCode() const
         } else if (originalNode) {
             // Add the event's home element to the scope
             // (and the document, and the form - see JSHTMLElement::eventHandlerScope)
-            ScopeChain scope = listener->scope();
+            ScopeChain scope = listenerAsFunction->scope();
 
             JSValue* thisObj = toJS(exec, originalNode);
             if (thisObj->isObject()) {
                 static_cast<DOMEventTargetNode*>(thisObj)->pushEventHandlerScope(exec, scope);
-                listener->setScope(scope);
+                listenerAsFunction->setScope(scope);
             }
         }
     }
diff --git a/WebCore/bindings/objc/WebScriptObjectInternal.h b/WebCore/bindings/objc/WebScriptObjectInternal.h
new file mode 100644 (file)
index 0000000..93544e1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+    Copyright (C) 2004 Apple Computer, Inc. All rights reserved.    
+*/
+#ifndef _WEB_SCRIPT_OBJECT_PRIVATE_H_
+#define _WEB_SCRIPT_OBJECT_PRIVATE_H_
+
+#import "WebScriptObject.h"
+
+#include <JavaScriptCore/internal.h>
+#include <JavaScriptCore/runtime_root.h>
+
+@interface WebScriptObject (Private)
++ (id)_convertValueToObjcValue:(KJS::JSValue *)value originExecutionContext:(const KJS::Bindings::RootObject *)originExecutionContext executionContext:(const KJS::Bindings::RootObject *)executionContext;
+- _init;
+- _initWithJSObject:(KJS::JSObject *)imp originExecutionContext:(const KJS::Bindings::RootObject *)originExecutionContext executionContext:(const KJS::Bindings::RootObject *)executionContext ;
+- (void)_initializeWithObjectImp:(KJS::JSObject *)imp originExecutionContext:(const KJS::Bindings::RootObject *)originExecutionContext executionContext:(const KJS::Bindings::RootObject *)executionContext ;
+- (void)_initializeScriptDOMNodeImp;
+- (KJS::JSObject *)_imp;
+- (void)_setExecutionContext:(const KJS::Bindings::RootObject *)context;
+- (const KJS::Bindings::RootObject *)_executionContext;
+- (void)_setOriginExecutionContext:(const KJS::Bindings::RootObject *)originExecutionContext;
+- (const KJS::Bindings::RootObject *)_originExecutionContext;
+@end
+
+@interface WebScriptObjectPrivate : NSObject
+{
+@public
+    KJS::JSObject *imp;
+    const KJS::Bindings::RootObject *executionContext;
+    const KJS::Bindings::RootObject *originExecutionContext;
+    BOOL isCreatedByDOMWrapper;
+}
+@end
+
+
+#endif