Commit 3412bb43 authored by weinig@apple.com's avatar weinig@apple.com

JavaScriptCore:

2008-09-01  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Darin Adler.

        First cut at inline caching for access to vanilla JavaScript properties.
        
        SunSpider says 4% faster. Tests heavy on dictionary-like access have
        regressed a bit -- we have a lot of room to improve in this area,
        but this patch is over-ripe as-is.
        
        JSCells now have a StructureID that uniquely identifies their layout,
        and holds their prototype.
        
        JSValue::put takes a PropertySlot& argument, so it can fill in details
        about where it put a value, for the sake of caching.

        * VM/CodeGenerator.cpp:
        (KJS::CodeGenerator::CodeGenerator): Avoid calling removeDirect if we
        can, since it disables inline caching in the global object. This can
        probably improve in the future.

        * kjs/JSGlobalObject.cpp: Nixed reset(), since it complicates caching, and
        wasn't really necessary.

        * kjs/JSObject.cpp: Tweaked getter / setter behavior not to rely on the
        IsGetterSetter flag, since the flag was buggy. This is necessary in order
        to avoid accidentally accessing a getter / setter as a normal property.
        
        Also changed getter / setter creation to honor ReadOnly, matching Mozilla.
        
        * kjs/PropertyMap.cpp: Nixed clear(), since it complicates caching and
        isn't necessary.

        * kjs/Shell.cpp: Moved SamplingTool dumping outside the loop. This allows
        you to aggregate sampling of multiple files (or the same file repeatedly),
        which helped me track down regressions.

        * kjs/ustring.h: Moved IdentifierRepHash here to share it.

WebCore:

2008-09-01  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Darin Adler.

        First cut at inline caching for access to vanilla JavaScript properties.

        Updated for JavaScriptCore changes. Mostly mechanical addition of StructureIDs
        to WebCore classes, and PutPropertySlot& arguments to put functions.

        (WebCore::JSCSSStyleDeclaration::customPut): Be sure to play nice with
        inline caching for global properties, so global assignment can be optimized.

        * ForwardingHeaders/kjs/StructureID.h: Added.
        * bindings/js/JSDOMBinding.h:
        (WebCore::DOMObject::DOMObject):
        * bindings/js/JSDOMWindowBase.cpp:
        (WebCore::JSDOMWindowBase::put):
        * bindings/js/JSDOMWindowBase.h:
        * bindings/js/JSDOMWindowCustom.h:
        (WebCore::JSDOMWindow::customPut):
        * bindings/js/JSDOMWindowShell.cpp:
        (WebCore::JSDOMWindowShell::JSDOMWindowShell):
        (WebCore::JSDOMWindowShell::put):
        * bindings/js/JSDOMWindowShell.h:
        * bindings/js/JSEventTargetBase.h:
        (WebCore::JSEventTargetBase::put):
        * bindings/js/JSEventTargetNode.h:
        (WebCore::JSEventTargetNode::put):
        * bindings/js/JSHTMLAppletElementCustom.cpp:
        (WebCore::JSHTMLAppletElement::customPut):
        * bindings/js/JSHTMLEmbedElementCustom.cpp:
        (WebCore::JSHTMLEmbedElement::customPut):
        * bindings/js/JSHTMLInputElementBase.cpp:
        (WebCore::JSHTMLInputElementBase::put):
        * bindings/js/JSHTMLInputElementBase.h:
        * bindings/js/JSHTMLObjectElementCustom.cpp:
        (WebCore::JSHTMLObjectElement::customPut):
        * bindings/js/JSHistoryCustom.cpp:
        (WebCore::JSHistory::customPut):
        * bindings/js/JSInspectedObjectWrapper.cpp:
        (WebCore::JSInspectedObjectWrapper::wrap):
        (WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper):
        * bindings/js/JSInspectedObjectWrapper.h:
        * bindings/js/JSInspectorCallbackWrapper.cpp:
        (WebCore::JSInspectorCallbackWrapper::wrap):
        (WebCore::JSInspectorCallbackWrapper::JSInspectorCallbackWrapper):
        * bindings/js/JSInspectorCallbackWrapper.h:
        * bindings/js/JSLocationCustom.cpp:
        (WebCore::JSLocation::customPut):
        * bindings/js/JSPluginElementFunctions.cpp:
        (WebCore::runtimeObjectCustomPut):
        * bindings/js/JSPluginElementFunctions.h:
        * bindings/js/JSQuarantinedObjectWrapper.cpp:
        (WebCore::JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper):
        (WebCore::JSQuarantinedObjectWrapper::put):
        * bindings/js/JSQuarantinedObjectWrapper.h:
        * bindings/js/JSStorageCustom.cpp:
        (WebCore::JSStorage::customPut):
        * bindings/objc/WebScriptObject.mm:
        (-[WebScriptObject setValue:forKey:]):
        * bindings/scripts/CodeGeneratorJS.pm:
        * bridge/NP_jsobject.cpp:
        (_NPN_SetProperty):
        * bridge/jni/jni_jsobject.mm:
        (JavaJSObject::setMember):
        * bridge/objc/objc_class.mm:
        (KJS::Bindings::ObjcClass::fallbackObject):
        * bridge/objc/objc_runtime.h:
        * bridge/objc/objc_runtime.mm:
        (ObjcFallbackObjectImp::ObjcFallbackObjectImp):
        (ObjcFallbackObjectImp::put):
        * bridge/runtime.cpp:
        (KJS::Bindings::Instance::createRuntimeObject):
        * bridge/runtime_array.cpp:
        (RuntimeArray::put):
        * bridge/runtime_array.h:
        * bridge/runtime_object.cpp:
        (RuntimeObjectImp::RuntimeObjectImp):
        (RuntimeObjectImp::put):
        * bridge/runtime_object.h:

LayoutTests:

2008-09-01  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Darin Adler.

        First cut at inline caching for access to vanilla JavaScript properties.
        
        Tests for things I broke along the way.
        
        * fast/dom/getter-on-window-object2-expected.txt:
        * fast/js/pic: Added.
        * fast/js/pic/cached-deleted-properties-expected.txt: Added.
        * fast/js/pic/cached-deleted-properties.html: Added.
        * fast/js/pic/cached-getter-dictionary-and-proto-expected.txt: Added.
        * fast/js/pic/cached-getter-dictionary-and-proto.html: Added.
        * fast/js/pic/cached-getter-setter-expected.txt: Added.
        * fast/js/pic/cached-getter-setter.html: Added.
        * fast/js/pic/cached-prototype-setter-expected.txt: Added.
        * fast/js/pic/cached-prototype-setter.html: Added.
        * fast/js/pic/cached-single-entry-transition-expected.txt: Added.
        * fast/js/pic/cached-single-entry-transition.html: Added.
        * fast/js/pic/get-empty-string-expected.txt: Added.
        * fast/js/pic/get-empty-string.html: Added.
        * fast/js/pic/get-set-proxy-object-expected.txt: Added.
        * fast/js/pic/get-set-proxy-object.html: Added.
        * fast/js/pic/rehash-poisons-structure-expected.txt: Added.
        * fast/js/pic/rehash-poisons-structure.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36016 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6976c61b
......@@ -36,8 +36,8 @@ namespace KJS {
template <class Base>
class JSCallbackObject : public Base {
public:
JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype, void* data);
JSCallbackObject(JSClassRef);
JSCallbackObject(ExecState*, JSClassRef, JSObject* prototype, void* data);
JSCallbackObject(JSGlobalData*, JSClassRef);
virtual ~JSCallbackObject();
void setPrivate(void* data);
......@@ -54,8 +54,7 @@ private:
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
virtual void put(ExecState*, const Identifier&, JSValue*);
virtual void put(ExecState*, unsigned, JSValue*);
virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier&);
virtual bool deleteProperty(ExecState*, unsigned);
......
......@@ -40,7 +40,7 @@
namespace KJS {
template <class Base>
JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSObject* prototype, void* data)
: Base(prototype)
, m_callbackObjectData(new JSCallbackObjectData(data, jsClass))
{
......@@ -50,8 +50,9 @@ JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JS
// Global object constructor.
// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
template <class Base>
JSCallbackObject<Base>::JSCallbackObject(JSClassRef jsClass)
: m_callbackObjectData(new JSCallbackObjectData(0, jsClass))
JSCallbackObject<Base>::JSCallbackObject(JSGlobalData* globalData, JSClassRef jsClass)
: Base(globalData)
, m_callbackObjectData(new JSCallbackObjectData(0, jsClass))
{
ASSERT(Base::isGlobalObject());
init(static_cast<JSGlobalObject*>(this)->globalExec());
......@@ -152,7 +153,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned proper
}
template <class Base>
void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
{
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(this);
......@@ -193,13 +194,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
}
}
return Base::put(exec, propertyName, value);
}
template <class Base>
void JSCallbackObject<Base>::put(ExecState* exec, unsigned propertyName, JSValue* value)
{
return put(exec, Identifier::from(exec, propertyName), value);
return Base::put(exec, propertyName, value, slot);
}
template <class Base>
......
......@@ -67,16 +67,16 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::create();
if (!globalObjectClass) {
JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject;
JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject(globalData.get());
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass);
JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalData.get(), globalObjectClass);
ExecState* exec = globalObject->globalExec();
JSValue* prototype = globalObjectClass->prototype(exec);
if (!prototype)
prototype = jsNull();
globalObject->reset(prototype);
globalObject->resetPrototype(prototype);
return JSGlobalContextRetain(toGlobalRef(exec));
}
......
......@@ -74,7 +74,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
if (!jsClass)
return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
JSValue* jsPrototype = jsClass->prototype(exec);
JSObject* jsPrototype = jsClass->prototype(exec);
if (!jsPrototype)
jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
......@@ -141,7 +141,7 @@ void JSObjectSetPrototype(JSContextRef, JSObjectRef object, JSValueRef value)
JSObject* jsObject = toJS(object);
JSValue* jsValue = toJS(value);
jsObject->setPrototype(jsValue);
jsObject->setPrototype(jsValue->isObject() ? jsValue : jsNull());
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
......@@ -184,8 +184,10 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
if (attributes && !jsObject->hasProperty(exec, name))
jsObject->putWithAttributes(exec, name, jsValue, attributes);
else
jsObject->put(exec, name, jsValue);
else {
PutPropertySlot slot;
jsObject->put(exec, name, jsValue, slot);
}
if (exec->hadException()) {
if (exception)
......
2008-09-01 Geoffrey Garen <ggaren@apple.com>
Reviewed by Darin Adler.
First cut at inline caching for access to vanilla JavaScript properties.
SunSpider says 4% faster. Tests heavy on dictionary-like access have
regressed a bit -- we have a lot of room to improve in this area,
but this patch is over-ripe as-is.
JSCells now have a StructureID that uniquely identifies their layout,
and holds their prototype.
JSValue::put takes a PropertySlot& argument, so it can fill in details
about where it put a value, for the sake of caching.
* VM/CodeGenerator.cpp:
(KJS::CodeGenerator::CodeGenerator): Avoid calling removeDirect if we
can, since it disables inline caching in the global object. This can
probably improve in the future.
* kjs/JSGlobalObject.cpp: Nixed reset(), since it complicates caching, and
wasn't really necessary.
* kjs/JSObject.cpp: Tweaked getter / setter behavior not to rely on the
IsGetterSetter flag, since the flag was buggy. This is necessary in order
to avoid accidentally accessing a getter / setter as a normal property.
Also changed getter / setter creation to honor ReadOnly, matching Mozilla.
* kjs/PropertyMap.cpp: Nixed clear(), since it complicates caching and
isn't necessary.
* kjs/Shell.cpp: Moved SamplingTool dumping outside the loop. This allows
you to aggregate sampling of multiple files (or the same file repeatedly),
which helped me track down regressions.
* kjs/ustring.h: Moved IdentifierRepHash here to share it.
2008-09-01 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
......
......@@ -105,8 +105,11 @@ __ZN3KJS11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E
__ZN3KJS11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEEPNS_14SourceProviderEbbi
__ZN3KJS11PropertyMap11getLocationERKNS_10IdentifierE
__ZN3KJS11PropertyMap11getLocationERKNS_10IdentifierERb
__ZN3KJS11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjb
__ZN3KJS11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotE
__ZN3KJS11PropertyMapD1Ev
__ZN3KJS11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierE
__ZN3KJS11StructureID25changePrototypeTransitionEPS0_PNS_7JSValueE
__ZN3KJS11StructureIDD1Ev
__ZN3KJS12DateInstance4infoE
__ZN3KJS12JSGlobalData6createEv
__ZN3KJS12JSGlobalDataD1Ev
......@@ -119,7 +122,7 @@ __ZN3KJS12StringObject14toThisJSStringEPNS_9ExecStateE
__ZN3KJS12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3KJS12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3KJS12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3KJS12StringObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS12StringObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
__ZN3KJS12StringObject4infoE
__ZN3KJS12StringObjectC2EPNS_9ExecStateEPNS_8JSObjectERKNS_7UStringE
__ZN3KJS13CodeGenerator21setDumpsGeneratedCodeEb
......@@ -132,7 +135,7 @@ __ZN3KJS14JSGlobalObject14setTimeoutTimeEj
__ZN3KJS14JSGlobalObject16stopTimeoutCheckEv
__ZN3KJS14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEj
__ZN3KJS14JSGlobalObject17startTimeoutCheckEv
__ZN3KJS14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
__ZN3KJS14JSGlobalObject4initEPNS_8JSObjectE
__ZN3KJS14JSGlobalObject4markEv
__ZN3KJS14JSGlobalObjectD2Ev
......@@ -178,7 +181,7 @@ __ZN3KJS6JSCell14toThisJSStringEPNS_9ExecStateE
__ZN3KJS6JSCell16getConstructDataERNS_13ConstructDataE
__ZN3KJS6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3KJS6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3KJS6JSCell3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS6JSCell3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
__ZN3KJS6JSCell3putEPNS_9ExecStateEjPNS_7JSValueE
__ZN3KJS6JSCell9getObjectEv
__ZN3KJS6JSCellnwEmPNS_9ExecStateE
......@@ -219,14 +222,16 @@ __ZN3KJS8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateEj
__ZN3KJS8JSObject14setStructureIDEN3WTF10PassRefPtrINS_11StructureIDEEE
__ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3KJS8JSObject17createInheritorIDEv
__ZN3KJS8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
__ZN3KJS8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEj
__ZN3KJS8JSObject17putWithAttributesEPNS_9ExecStateEjPNS_7JSValueEj
__ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
__ZN3KJS8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
__ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
__ZN3KJS8JSObject3putEPNS_9ExecStateEjPNS_7JSValueE
__ZN3KJS8JSObject4markEv
__ZN3KJS8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
......@@ -234,6 +239,8 @@ __ZN3KJS8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringEPNS_14ProfilerCli
__ZN3KJS8Profiler21didFinishAllExecutionEPNS_9ExecStateE
__ZN3KJS8Profiler8profilerEv
__ZN3KJS8jsStringEPNS_9ExecStateERKNS_7UStringE
__ZN3KJS9CodeBlockD1Ev
__ZN3KJS9CodeBlockD2Ev
__ZN3KJS9constructEPNS_9ExecStateEPNS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
__ZN3KJSeqERKNS_7UStringEPKc
__ZN3KJSgtERKNS_7UStringES2_
......@@ -325,6 +332,7 @@ __ZNK3KJS8JSObject8toObjectEPNS_9ExecStateE
__ZNK3KJS8JSObject8toStringEPNS_9ExecStateE
__ZNK3KJS8JSObject9classNameEv
__ZNK3KJS8JSObject9toBooleanEPNS_9ExecStateE
__ZNK3KJS9CodeBlock17derefStructureIDsEPNS_11InstructionE
__ZNK3KJS9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3WTF8Collator7collateEPKtmS2_m
__ZTVN3KJS12JSNumberCellE
......
......@@ -276,6 +276,8 @@
BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203460E17135E002C7E82 /* DateConstructor.h */; };
BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203480E17135E002C7E82 /* DatePrototype.h */; };
BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */; };
BCDE3AB80E6C82F5001453A7 /* StructureID.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDE3AB10E6C82CF001453A7 /* StructureID.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCDE3B430E6C832D001453A7 /* StructureID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDE3AB00E6C82CF001453A7 /* StructureID.cpp */; };
BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
C0A272630E50A06300E96E15 /* NotFound.h in Headers */ = {isa = PBXBuildFile; fileRef = C0A2723F0E509F1E00E96E15 /* NotFound.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -708,6 +710,8 @@
BCD203470E17135E002C7E82 /* DatePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatePrototype.cpp; sourceTree = "<group>"; };
BCD203480E17135E002C7E82 /* DatePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatePrototype.h; sourceTree = "<group>"; };
BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatePrototype.lut.h; sourceTree = "<group>"; };
BCDE3AB00E6C82CF001453A7 /* StructureID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureID.cpp; sourceTree = "<group>"; };
BCDE3AB10E6C82CF001453A7 /* StructureID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureID.h; sourceTree = "<group>"; };
BCF605110E203EF800B9A64D /* ArgList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArgList.cpp; sourceTree = "<group>"; };
BCF605120E203EF800B9A64D /* ArgList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgList.h; sourceTree = "<group>"; };
BCF6553B0A2048DE0038A194 /* MathExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MathExtras.h; sourceTree = "<group>"; };
......@@ -1133,10 +1137,10 @@
BCD203460E17135E002C7E82 /* DateConstructor.h */,
BC1166000E1997B1008066DD /* DateInstance.cpp */,
BC1166010E1997B1008066DD /* DateInstance.h */,
BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
BCD203480E17135E002C7E82 /* DatePrototype.h */,
D21202280AD4310C00ED79B6 /* DateMath.cpp */,
D21202290AD4310C00ED79B6 /* DateMath.h */,
BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
BCD203480E17135E002C7E82 /* DatePrototype.h */,
651F6412039D5B5F0078395C /* dtoa.cpp */,
651F6413039D5B5F0078395C /* dtoa.h */,
BC337BEA0E1B00CB0076918A /* Error.cpp */,
......@@ -1153,11 +1157,11 @@
BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
933A3499038AE7C6008635CE /* grammar.y */,
BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
BC257DED0E1F52ED0016B6C9 /* GlobalEvalFunction.cpp */,
BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */,
933A3499038AE7C6008635CE /* grammar.y */,
933A349D038AE80F008635CE /* identifier.cpp */,
933A349A038AE7C6008635CE /* identifier.h */,
BC257DE90E1F52BA0016B6C9 /* IndexToNameMap.cpp */,
......@@ -1192,8 +1196,8 @@
BC7F8FB80E19D1C3008632C0 /* JSNumberCell.h */,
BC22A3980E16E14800AF21C8 /* JSObject.cpp */,
BC22A3990E16E14800AF21C8 /* JSObject.h */,
A7E42C180E3938830065A544 /* JSStaticScopeObject.h */,
A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */,
A7E42C180E3938830065A544 /* JSStaticScopeObject.h */,
BC02E9B60E1842FA000F9297 /* JSString.cpp */,
F692A8620255597D01FF60F7 /* JSString.h */,
14ABB454099C2A0F00E2A24F /* JSType.h */,
......@@ -1232,9 +1236,9 @@
65400C100A69BAF200509887 /* PropertyNameArray.h */,
65621E6B089E859700760F35 /* PropertySlot.cpp */,
65621E6C089E859700760F35 /* PropertySlot.h */,
65C02FBB0637462A003E7EE6 /* protect.h */,
BC257DF10E1F53740016B6C9 /* PrototypeFunction.cpp */,
BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */,
65C02FBB0637462A003E7EE6 /* protect.h */,
F692A87D0255597D01FF60F7 /* regexp.cpp */,
F692A87E0255597D01FF60F7 /* regexp.h */,
BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */,
......@@ -1257,6 +1261,8 @@
BC18C3C40E16EE3300B34460 /* StringObjectThatMasqueradesAsUndefined.h */,
BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */,
BC18C3C60E16EE3300B34460 /* StringPrototype.h */,
BCDE3AB00E6C82CF001453A7 /* StructureID.cpp */,
BCDE3AB10E6C82CF001453A7 /* StructureID.h */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
5D53726D0E1C546B0021E549 /* Tracing.d */,
5D53726E0E1C54880021E549 /* Tracing.h */,
......@@ -1538,6 +1544,7 @@
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
933040040E6A749400786E6A /* SmallStrings.h in Headers */,
BCDE3AB80E6C82F5001453A7 /* StructureID.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1845,6 +1852,7 @@
E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */,
95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */,
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
BCDE3B430E6C832D001453A7 /* StructureID.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
This diff is collapsed.
......@@ -80,6 +80,7 @@ namespace KJS {
struct CodeBlock {
CodeBlock(ScopeNode* ownerNode_, CodeType codeType_, PassRefPtr<SourceProvider> source_, unsigned sourceOffset_)
: ownerNode(ownerNode_)
, globalData(0)
, numTemporaries(0)
, numVars(0)
, numParameters(0)
......@@ -91,16 +92,24 @@ namespace KJS {
, sourceOffset(sourceOffset_)
{
}
~CodeBlock();
#if !defined(NDEBUG) || ENABLE_SAMPLING_TOOL
#if !defined(NDEBUG) || ENABLE(SAMPLING_TOOL)
void dump(ExecState*) const;
void printStructureIDs(const Instruction*) const;
void printStructureID(const char* name, const Instruction*, int operand) const;
#endif
int expressionRangeForVPC(const Instruction*, int& divot, int& startOffset, int& endOffset);
int lineNumberForVPC(const Instruction* vPC);
bool getHandlerForVPC(const Instruction* vPC, Instruction*& target, int& scopeDepth);
void mark();
void refStructureIDs(Instruction* vPC) const;
void derefStructureIDs(Instruction* vPC) const;
ScopeNode* ownerNode;
JSGlobalData* globalData;
int numConstants;
int numTemporaries;
......@@ -115,6 +124,7 @@ namespace KJS {
unsigned sourceOffset;
Vector<Instruction> instructions;
Vector<size_t> structureIDInstructions;
// Constant pool
Vector<Identifier> identifiers;
......@@ -132,7 +142,7 @@ namespace KJS {
Vector<StringJumpTable> stringSwitchJumpTables;
private:
#if !defined(NDEBUG) || ENABLE_SAMPLING_TOOL
#if !defined(NDEBUG) || ENABLE(SAMPLING_TOOL)
void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
#endif
};
......
......@@ -200,6 +200,8 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
{
codeBlock->globalData = m_globalData;
// FIXME: Move code that modifies the global object to Machine::execute.
m_codeBlock->numConstants = programNode->neededConstants();
......@@ -225,7 +227,8 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
for (size_t i = 0; i < functionStack.size(); ++i) {
FuncDeclNode* funcDecl = functionStack[i].get();
globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property.
if (globalObject->getDirect(funcDecl->m_ident))
globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property.
emitNewFunction(addGlobalVar(funcDecl->m_ident, false), funcDecl);
}
......@@ -263,6 +266,8 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
{
codeBlock->globalData = m_globalData;
m_codeBlock->numConstants = functionBody->neededConstants();
const Node::FunctionStack& functionStack = functionBody->functionStack();
......@@ -309,6 +314,8 @@ CodeGenerator::CodeGenerator(EvalNode* evalNode, const Debugger* debugger, const
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
{
codeBlock->globalData = m_globalData;
m_codeBlock->numConstants = evalNode->neededConstants();
m_codeBlock->numVars = 1; // Allocate space for "this"
}
......@@ -668,13 +675,6 @@ RegisterID* CodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
return dst;
}
RegisterID* CodeGenerator::emitNullaryOp(OpcodeID opcode, RegisterID* dst)
{
emitOpcode(opcode);
instructions().append(dst->index());
return dst;
}
bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting)
{
// Cases where we cannot optimise the lookup
......@@ -788,19 +788,29 @@ RegisterID* CodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID*
RegisterID* CodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
{
m_codeBlock->structureIDInstructions.append(instructions().size());
emitOpcode(op_get_by_id);
instructions().append(dst->index());
instructions().append(base->index());
instructions().append(addConstant(property));
instructions().append(0);
instructions().append(0);
instructions().append(0);
instructions().append(0);
return dst;
}
RegisterID* CodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
{
m_codeBlock->structureIDInstructions.append(instructions().size());
emitOpcode(op_put_by_id);
instructions().append(base->index());
instructions().append(addConstant(property));
instructions().append(value->index());
instructions().append(0);
instructions().append(0);
return value;
}
......@@ -867,6 +877,13 @@ RegisterID* CodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, Regi
return value;
}
RegisterID* CodeGenerator::emitNewObject(RegisterID* dst)
{
emitOpcode(op_new_object);
instructions().append(dst->index());
return dst;
}
RegisterID* CodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
{
Vector<RefPtr<RegisterID>, 16> argv;
......
......@@ -232,12 +232,11 @@ namespace KJS {
RegisterID* emitUnexpectedLoad(RegisterID* dst, bool);
RegisterID* emitUnexpectedLoad(RegisterID* dst, double);
RegisterID* emitNullaryOp(OpcodeID, RegisterID* dst);
RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
RegisterID* emitNewObject(RegisterID* dst) { return emitNullaryOp(op_new_object, dst); }
RegisterID* emitNewObject(RegisterID* dst);
RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision
RegisterID* emitNewFunction(RegisterID* dst, FuncDeclNode* func);
......@@ -346,7 +345,7 @@ namespace KJS {
static const bool needsRef = false;
};
typedef HashMap<RefPtr<UString::Rep>, int, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap;
typedef HashMap<RefPtr<UString::Rep>, int, WTF::IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap;
RegisterID* emitCall(OpcodeID, RegisterID*, RegisterID*, RegisterID*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
......@@ -381,6 +380,7 @@ namespace KJS {
RegisterID* addConstant(JSValue*);
unsigned addUnexpectedConstant(JSValue*);
unsigned addRegExp(RegExp* r);
StructureID* addStructureID();
Vector<Instruction>& instructions() { return m_codeBlock->instructions; }
SymbolTable& symbolTable() { return *m_symbolTable; }
......@@ -397,7 +397,7 @@ namespace KJS {
ScopeNode* m_scopeNode;
CodeBlock* m_codeBlock;
HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions;
HashSet<RefPtr<UString::Rep>, WTF::IdentifierRepHash> m_functions;
RegisterID m_thisRegister;
SegmentedVector<RegisterID, 512> m_locals;
SegmentedVector<RegisterID, 512> m_constants;
......
......@@ -49,12 +49,17 @@ static void substitute(UString& string, const UString& substring)
class InterruptedExecutionError : public JSObject {
public:
InterruptedExecutionError(ExecState* exec)
: JSObject(exec->globalData().nullProtoStructureID)
{
}
virtual bool isWatchdogException() const { return true; }
};
JSValue* createInterruptedExecutionException(ExecState* exec)
{
return new (exec) InterruptedExecutionError;
return new (exec) InterruptedExecutionError(exec);
}
JSValue* createError(ExecState* exec, ErrorType e, const char* msg)
......@@ -197,7 +202,7 @@ JSValue* createNotAFunctionError(ExecState* exec, JSValue* value, const Instruct
JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState* exec, bool isNull)
{
return new (exec) JSNotAnObjectErrorStub(isNull);
return new (exec) JSNotAnObjectErrorStub(exec, isNull);
}
JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, const Instruction* vPC, CodeBlock* codeBlock)
......
......@@ -33,13 +33,23 @@
namespace KJS {
class JSCell;
class StructureID;
class StructureIDChain;
struct Instruction {
Instruction(Opcode opcode) { u.opcode = opcode; }
Instruction(int operand) { u.operand = operand; }
Instruction(StructureID* structureID) { u.structureID = structureID; }
Instruction(StructureIDChain* structureIDChain) { u.structureIDChain = structureIDChain; }
Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
union {
Opcode opcode;
int operand;
StructureID* structureID;
StructureIDChain* structureIDChain;
JSCell* jsCell;
} u;
};
......
This diff is collapsed.
......@@ -151,6 +151,11 @@ namespace KJS {
bool isJSArray(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsArrayVptr; }
bool isJSString(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsStringVptr; }
void tryCacheGetByID(CodeBlock*, Instruction* vPC, JSValue* baseValue, const PropertySlot&);
void uncacheGetByID(CodeBlock*, Instruction* vPC);
void tryCachePutByID(CodeBlock*, Instruction* vPC, JSValue* baseValue, const PutPropertySlot&);
void uncachePutByID(CodeBlock*, Instruction* vPC);
int m_reentryDepth;
unsigned m_timeoutTime;
unsigned m_timeAtLastCheckTimeout;
......
......@@ -86,7 +86,13 @@ namespace KJS {
macro(op_resolve_with_base) \
macro(op_resolve_func) \
macro(op_get_by_id) \