Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: bindings/v8/V8Proxy.cpp

Issue 151078: Speed up creation of DOM node wrappers (Closed) Base URL: http://svn.webkit.org/repository/webkit/trunk/WebCore/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « bindings/v8/V8Proxy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 if (value.IsEmpty()) 1212 if (value.IsEmpty())
1213 return v8::Local<v8::Function>(); 1213 return v8::Local<v8::Function>();
1214 // Hotmail fix, see comments above. 1214 // Hotmail fix, see comments above.
1215 value->Set(v8::String::New("__proto__"), m_objectPrototype); 1215 value->Set(v8::String::New("__proto__"), m_objectPrototype);
1216 return value; 1216 return value;
1217 } 1217 }
1218 1218
1219 v8::Local<v8::Object> V8Proxy::createWrapperFromCache(V8ClassIndex::V8WrapperTyp e type) 1219 v8::Local<v8::Object> V8Proxy::createWrapperFromCache(V8ClassIndex::V8WrapperTyp e type)
1220 { 1220 {
1221 int classIndex = V8ClassIndex::ToInt(type); 1221 int classIndex = V8ClassIndex::ToInt(type);
1222 v8::Local<v8::Value> cachedObject = m_wrapperBoilerplates->Get(v8::Integer:: New(classIndex)); 1222 v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex ));
1223 if (cachedObject->IsObject()) { 1223 if (!clone.IsEmpty())
1224 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(cachedObject) ; 1224 return clone;
1225 return object->Clone();
1226 }
1227 1225
1228 // Not in cache. 1226 // Not in cache.
1229 initContextIfNeeded(); 1227 initContextIfNeeded();
1230 v8::Context::Scope scope(m_context); 1228 v8::Context::Scope scope(m_context);
1231 v8::Local<v8::Function> function = getConstructor(type); 1229 v8::Local<v8::Function> function = getConstructor(type);
1232 v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); 1230 v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
1233 if (!instance.IsEmpty()) { 1231 if (!instance.IsEmpty()) {
1234 m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance); 1232 m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance);
1235 return instance->Clone(); 1233 return instance->Clone();
1236 } 1234 }
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2400 // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterConditio n. 2398 // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterConditio n.
2401 // In NodeFilterCondition, filter object is persisted in its constructor, 2399 // In NodeFilterCondition, filter object is persisted in its constructor,
2402 // and disposed in its destructor. 2400 // and disposed in its destructor.
2403 if (!filter->IsFunction()) 2401 if (!filter->IsFunction())
2404 return 0; 2402 return 0;
2405 2403
2406 NodeFilterCondition* condition = new V8NodeFilterCondition(filter); 2404 NodeFilterCondition* condition = new V8NodeFilterCondition(filter);
2407 return NodeFilter::create(condition); 2405 return NodeFilter::create(condition);
2408 } 2406 }
2409 2407
2410 v8::Local<v8::Object> V8Proxy::instantiateV8Object(V8ClassIndex::V8WrapperType d escriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl) 2408 v8::Local<v8::Object> V8Proxy::instantiateV8Object(V8Proxy* proxy, V8ClassIndex: :V8WrapperType descriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl)
2411 { 2409 {
2412 // Make a special case for document.all 2410 // Make a special case for document.all
2413 if (descriptorType == V8ClassIndex::HTMLCOLLECTION && static_cast<HTMLCollec tion*>(impl)->type() == DocAll) 2411 if (descriptorType == V8ClassIndex::HTMLCOLLECTION && static_cast<HTMLCollec tion*>(impl)->type() == DocAll)
2414 descriptorType = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; 2412 descriptorType = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION;
2415 2413
2416 V8Proxy* proxy = V8Proxy::retrieve(); 2414 if (!proxy)
2415 V8Proxy* proxy = V8Proxy::retrieve();
2417 v8::Local<v8::Object> instance; 2416 v8::Local<v8::Object> instance;
2418 if (proxy) 2417 if (proxy)
2419 instance = proxy->createWrapperFromCache(descriptorType); 2418 instance = proxy->createWrapperFromCache(descriptorType);
2420 else { 2419 else {
2421 v8::Local<v8::Function> function = getTemplate(descriptorType)->GetFunct ion(); 2420 v8::Local<v8::Function> function = getTemplate(descriptorType)->GetFunct ion();
2422 instance = SafeAllocation::newInstance(function); 2421 instance = SafeAllocation::newInstance(function);
2423 } 2422 }
2424 if (!instance.IsEmpty()) { 2423 if (!instance.IsEmpty()) {
2425 // Avoid setting the DOM wrapper for failed allocations. 2424 // Avoid setting the DOM wrapper for failed allocations.
2426 setDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl); 2425 setDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2777 // in case the event is NULL. 2776 // in case the event is NULL.
2778 return v8::Null(); 2777 return v8::Null();
2779 } 2778 }
2780 2779
2781 event->ref(); // fast ref 2780 event->ref(); // fast ref
2782 setJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result)); 2781 setJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result));
2783 2782
2784 return result; 2783 return result;
2785 } 2784 }
2786 2785
2786
2787 static const V8ClassIndex::V8WrapperType mapping[] = {
2788 V8ClassIndex::INVALID_CLASS_INDEX, // NONE
2789 V8ClassIndex::INVALID_CLASS_INDEX, // ELEMENT_NODE needs special treatment
2790 V8ClassIndex::ATTR, // ATTRIBUTE_NODE
2791 V8ClassIndex::TEXT, // TEXT_NODE
2792 V8ClassIndex::CDATASECTION, // CDATA_SECTION_NODE
2793 V8ClassIndex::ENTITYREFERENCE, // ENTITY_REFERENCE_NODE
2794 V8ClassIndex::ENTITY, // ENTITY_NODE
2795 V8ClassIndex::PROCESSINGINSTRUCTION, // PROCESSING_INSTRUCTION_NODE
2796 V8ClassIndex::COMMENT, // COMMENT_NODE
2797 V8ClassIndex::INVALID_CLASS_INDEX, // DOCUMENT_NODE needs special treatment
2798 V8ClassIndex::DOCUMENTTYPE, // DOCUMENT_TYPE_NODE
2799 V8ClassIndex::DOCUMENTFRAGMENT, // DOCUMENT_FRAGMENT_NODE
2800 V8ClassIndex::NOTATION, // NOTATION_NODE
2801 V8ClassIndex::NODE, // XPATH_NAMESPACE_NODE
2802 };
2803
2787 // Caller checks node is not null. 2804 // Caller checks node is not null.
2788 v8::Handle<v8::Value> V8Proxy::convertNodeToV8Object(Node* node) 2805 v8::Handle<v8::Value> V8Proxy::convertNodeToV8Object(Node* node)
2789 { 2806 {
2790 if (!node) 2807 if (!node)
2791 return v8::Null(); 2808 return v8::Null();
2792 2809
2793 // Find the context to which the node belongs and create the wrapper 2810 // Find a proxy for this node.
2794 // in that context. If the node is not in a document, the current
2795 // context is used.
2796 // 2811 //
2797 // Getting the context might initialize the context which can instantiate 2812 // Note that if proxy is found, we might initialize the context which can
2798 // a document wrapper. Therefore, we get the context before checking if 2813 // instantiate a document wrapper. Therefore, we get the proxy before
2799 // the node already has a wrapper. 2814 // checking if the node already has a wrapper.
2800 v8::Local<v8::Context> v8Context; 2815 V8Proxy* proxy = 0;
2801 Document* document = node->document(); 2816 Document* document = node->document();
2802 if (document) 2817 if (document) {
2803 v8Context = V8Proxy::context(document->frame()); 2818 Frame* frame = document->frame();
2819 proxy = retrieve(frame);
2820 if (proxy)
2821 proxy->initContextIfNeeded();
2822 }
2804 2823
2805 v8::Handle<v8::Object> wrapper = getDOMNodeMap().get(node); 2824 DOMWrapperMap<Node>& domNodeMap = proxy ? proxy->m_domNodeMap : getDOMNodeMa p();
2825 v8::Handle<v8::Object> wrapper = domNodeMap.get(node);
2806 if (!wrapper.IsEmpty()) 2826 if (!wrapper.IsEmpty())
2807 return wrapper; 2827 return wrapper;
2808 2828
2809 bool isDocument = false; // document type node has special handling 2829 bool isDocument = false; // document type node has special handling
2810 V8ClassIndex::V8WrapperType type; 2830 V8ClassIndex::V8WrapperType type;
2811 2831
2812 switch (node->nodeType()) { 2832 Node::NodeType nodeType = node->nodeType();
2813 case Node::ELEMENT_NODE: 2833 if (nodeType == Node::ELEMENT_NODE) {
2814 if (node->isHTMLElement()) 2834 if (node->isHTMLElement())
2815 type = htmlElementType(static_cast<HTMLElement*>(node)); 2835 type = htmlElementType(static_cast<HTMLElement*>(node));
2816 #if ENABLE(SVG) 2836 #if ENABLE(SVG)
2817 else if (node->isSVGElement()) 2837 else if (node->isSVGElement())
2818 type = svgElementType(static_cast<SVGElement*>(node)); 2838 type = svgElementType(static_cast<SVGElement*>(node));
2819 #endif 2839 #endif
2820 else 2840 else
2821 type = V8ClassIndex::ELEMENT; 2841 type = V8ClassIndex::ELEMENT;
2822 break; 2842 } else if (nodeType == Node::DOCUMENT_NODE) {
2823 case Node::ATTRIBUTE_NODE: 2843 isDocument = true;
2824 type = V8ClassIndex::ATTR; 2844 Document* document = static_cast<Document*>(node);
2825 break; 2845 if (document->isHTMLDocument())
2826 case Node::TEXT_NODE: 2846 type = V8ClassIndex::HTMLDOCUMENT;
2827 type = V8ClassIndex::TEXT;
2828 break;
2829 case Node::CDATA_SECTION_NODE:
2830 type = V8ClassIndex::CDATASECTION;
2831 break;
2832 case Node::ENTITY_NODE:
2833 type = V8ClassIndex::ENTITY;
2834 break;
2835 case Node::PROCESSING_INSTRUCTION_NODE:
2836 type = V8ClassIndex::PROCESSINGINSTRUCTION;
2837 break;
2838 case Node::COMMENT_NODE:
2839 type = V8ClassIndex::COMMENT;
2840 break;
2841 case Node::DOCUMENT_NODE: {
2842 isDocument = true;
2843 Document* document = static_cast<Document*>(node);
2844 if (document->isHTMLDocument())
2845 type = V8ClassIndex::HTMLDOCUMENT;
2846 #if ENABLE(SVG) 2847 #if ENABLE(SVG)
2847 else if (document->isSVGDocument()) 2848 else if (document->isSVGDocument())
2848 type = V8ClassIndex::SVGDOCUMENT; 2849 type = V8ClassIndex::SVGDOCUMENT;
2849 #endif 2850 #endif
2850 else 2851 else
2851 type = V8ClassIndex::DOCUMENT; 2852 type = V8ClassIndex::DOCUMENT;
2852 break; 2853 } else {
2854 ASSERT(nodeType < sizeof(mapping)/sizeof(mapping[0]));
2855 type = mapping[nodeType];
2856 ASSERT(type != V8ClassIndex::INVALID_CLASS_INDEX);
2853 } 2857 }
2854 case Node::DOCUMENT_TYPE_NODE: 2858
2855 type = V8ClassIndex::DOCUMENTTYPE; 2859 v8::Local<v8::Context> v8Context;
2856 break; 2860 if (proxy)
2857 case Node::NOTATION_NODE: 2861 v8Context = proxy->context();
2858 type = V8ClassIndex::NOTATION;
2859 break;
2860 case Node::DOCUMENT_FRAGMENT_NODE:
2861 type = V8ClassIndex::DOCUMENTFRAGMENT;
2862 break;
2863 case Node::ENTITY_REFERENCE_NODE:
2864 type = V8ClassIndex::ENTITYREFERENCE;
2865 break;
2866 default:
2867 type = V8ClassIndex::NODE;
2868 }
2869 2862
2870 // Enter the node's context and create the wrapper in that context. 2863 // Enter the node's context and create the wrapper in that context.
2871 if (!v8Context.IsEmpty()) 2864 if (!v8Context.IsEmpty())
2872 v8Context->Enter(); 2865 v8Context->Enter();
2873 2866
2874 v8::Local<v8::Object> result = instantiateV8Object(type, V8ClassIndex::NODE, node); 2867 v8::Local<v8::Object> result = instantiateV8Object(proxy, type, V8ClassIndex ::NODE, node);
2875 2868
2876 // Exit the node's context if it was entered. 2869 // Exit the node's context if it was entered.
2877 if (!v8Context.IsEmpty()) 2870 if (!v8Context.IsEmpty())
2878 v8Context->Exit(); 2871 v8Context->Exit();
2879 2872
2880 if (result.IsEmpty()) { 2873 if (result.IsEmpty()) {
2881 // If instantiation failed it's important not to add the result 2874 // If instantiation failed it's important not to add the result
2882 // to the DOM node map. Instead we return an empty handle, which 2875 // to the DOM node map. Instead we return an empty handle, which
2883 // should already be handled by callers of this function in case 2876 // should already be handled by callers of this function in case
2884 // the node is NULL. 2877 // the node is NULL.
2885 return result; 2878 return result;
2886 } 2879 }
2887 2880
2888 node->ref(); 2881 node->ref();
2889 setJSWrapperForDOMNode(node, v8::Persistent<v8::Object>::New(result)); 2882 domNodeMap.set(node, v8::Persistent<v8::Object>::New(result));
2890 2883
2891 if (isDocument) { 2884 if (isDocument) {
2892 Document* document = static_cast<Document*>(node);
2893 V8Proxy* proxy = V8Proxy::retrieve(document->frame());
2894 if (proxy) 2885 if (proxy)
2895 proxy->updateDocumentWrapper(result); 2886 proxy->updateDocumentWrapper(result);
2896 2887
2897 if (type == V8ClassIndex::HTMLDOCUMENT) { 2888 if (type == V8ClassIndex::HTMLDOCUMENT) {
2898 // Create marker object and insert it in two internal fields. 2889 // Create marker object and insert it in two internal fields.
2899 // This is used to implement temporary shadowing of 2890 // This is used to implement temporary shadowing of
2900 // document.all. 2891 // document.all.
2901 ASSERT(result->InternalFieldCount() == V8Custom::kHTMLDocumentIntern alFieldCount); 2892 ASSERT(result->InternalFieldCount() == V8Custom::kHTMLDocumentIntern alFieldCount);
2902 v8::Local<v8::Object> marker = v8::Object::New(); 2893 v8::Local<v8::Object> marker = v8::Object::New();
2903 result->SetInternalField(V8Custom::kHTMLDocumentMarkerIndex, marker) ; 2894 result->SetInternalField(V8Custom::kHTMLDocumentMarkerIndex, marker) ;
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
3246 int V8Proxy::contextDebugId(v8::Handle<v8::Context> context) 3237 int V8Proxy::contextDebugId(v8::Handle<v8::Context> context)
3247 { 3238 {
3248 v8::HandleScope scope; 3239 v8::HandleScope scope;
3249 if (!context->GetData()->IsObject()) 3240 if (!context->GetData()->IsObject())
3250 return -1; 3241 return -1;
3251 v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String ::New(kContextDebugDataValue)); 3242 v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String ::New(kContextDebugDataValue));
3252 return data->IsInt32() ? data->Int32Value() : -1; 3243 return data->IsInt32() ? data->Int32Value() : -1;
3253 } 3244 }
3254 3245
3255 } // namespace WebCore 3246 } // namespace WebCore
OLDNEW
« no previous file with comments | « bindings/v8/V8Proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698