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

Unified Diff: src/elements.cc

Issue 7527001: Encapsulate element handling into a class keyed on ElementsKind (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: performance fixes Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | src/objects.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ff00e94f26260e8cde3a25d6ad02dfea129340d0
--- /dev/null
+++ b/src/elements.cc
@@ -0,0 +1,297 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "objects.h"
+#include "elements.h"
+
+namespace v8 {
+namespace internal {
+
+
+// Base class for element handler implementations. Contains the
+// the common logic for objects with different ElementsKinds.
+// Subclasses must specialize method for which the element
+// implementation differs from the base class implementation.
+//
+// This class is intended to be used in the following way:
+//
+// class SomeElementsHandlerImpl :
+// public ElementsHandlerImpl<SomeElementsHandlerImpl> {
Jakob Kummerow 2011/07/30 10:29:21 nit: second template argument (BackingStoreClass)
danno 2011/07/30 13:10:10 Done.
+// ...
+// }
+//
+// This is an example of Curiously recurring template pattern
+// (see http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
+// We use CRTP to guarantee aggressive compile time optimizations (i.e.
+// inlining and specialization of SomeElementsHandlerImpl methods).
+template <typename ConcreteHandlerImpl, typename BackingStoreClass>
+class ElementsHandlerImpl {
+ public:
+ static MaybeObject* GetWithReceiver(JSObject* obj,
+ Object* receiver,
+ uint32_t index) {
+ if (index < ConcreteHandlerImpl::GetLength(obj)) {
+ BackingStoreClass* backing_store =
+ ElementsHandlerImpl::GetBackingStore(obj);
+ MaybeObject* result = backing_store->get(index);
+ if (!result->IsTheHole()) return result;
+ }
+
+ Object* pt = obj->GetPrototype();
+ Heap* heap = obj->GetHeap();
+ if (pt == heap->null_value()) return heap->undefined_value();
+ return pt->GetElementWithReceiver(receiver, index);
+ }
+
+ protected:
+ static BackingStoreClass* GetBackingStore(JSObject* obj) {
+ return BackingStoreClass::cast(obj->elements());
+ }
+
+ static uint32_t GetLength(JSObject* obj) {
+ return ConcreteHandlerImpl::GetBackingStore(obj)->length();
+ }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ElementsHandlerImpl);
+};
+
+
+class FastElementsHandlerImpl
+ : public ElementsHandlerImpl< FastElementsHandlerImpl, FixedArray> {
Jakob Kummerow 2011/07/30 10:29:21 nit: extra space
danno 2011/07/30 13:10:10 Done.
+};
+
+
+class FastDoubleElementsHandlerImpl
+ : public ElementsHandlerImpl<FastDoubleElementsHandlerImpl,
+ FixedDoubleArray> {
+};
+
+
+// Super class for all external element arrays, whose handler implementation is
+// identical except for specialization.
+template<typename ConcreteExternalElementHandlerImpl,
+ typename ExternalArray>
+class ExternalElementsHandlerImpl
+ : public ElementsHandlerImpl<ConcreteExternalElementHandlerImpl,
+ ExternalArray> {
+};
+
+
+class ExternalByteElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<ExternalByteElementsHandlerImpl,
+ ExternalByteArray> {
+};
+
+
+class ExternalUnsignedByteElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<
+ ExternalUnsignedByteElementsHandlerImpl, ExternalUnsignedByteArray> {
+};
+
+
+class ExternalShortElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<ExternalShortElementsHandlerImpl,
+ ExternalShortArray> {
+};
+
+
+class ExternalUnsignedShortElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<
+ ExternalUnsignedShortElementsHandlerImpl, ExternalUnsignedShortArray> {
+};
+
+
+class ExternalIntElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<ExternalIntElementsHandlerImpl,
+ ExternalIntArray> {
+};
+
+
+class ExternalUnsignedIntElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<ExternalUnsignedIntElementsHandlerImpl,
+ ExternalUnsignedIntArray> {
+};
+
+
+class ExternalFloatElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<ExternalFloatElementsHandlerImpl,
+ ExternalFloatArray> {
+};
+
+
+class ExternalDoubleElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<ExternalDoubleElementsHandlerImpl,
+ ExternalDoubleArray> {
+};
+
+
+class PixelElementsHandlerImpl
+ : public ExternalElementsHandlerImpl<PixelElementsHandlerImpl,
+ ExternalPixelArray> {
+};
+
+
+class DictionaryElementsHandlerImpl
+ : public ElementsHandlerImpl<DictionaryElementsHandlerImpl,
+ NumberDictionary> {
+ public:
+ static MaybeObject* GetNumberDictionaryElement(
+ JSObject* obj,
+ Object* receiver,
+ NumberDictionary* backing_store,
+ uint32_t index) {
+ int entry = backing_store->FindEntry(index);
+ if (entry != NumberDictionary::kNotFound) {
+ Object* element = backing_store->ValueAt(entry);
+ PropertyDetails details = backing_store->DetailsAt(entry);
+ if (details.type() == CALLBACKS) {
+ return obj->GetElementWithCallback(receiver,
+ element,
+ index,
+ obj);
+ }
+ return element;
+ }
+ return obj->GetHeap()->the_hole_value();
+ }
+
+ static MaybeObject* GetWithReceiver(JSObject* obj,
+ Object* receiver,
+ uint32_t index) {
+ NumberDictionary* backing_store = GetBackingStore(obj);
+ return GetNumberDictionaryElement(obj, receiver, backing_store, index);
+ }
+
+ protected:
+ static NumberDictionary* GetBackingStore(JSObject* obj) {
+ return NumberDictionary::cast(obj->element_dictionary());
+ }
+};
+
+
+class NonStrictArgumentsElementsHandlerImpl
+ : public ElementsHandlerImpl<NonStrictArgumentsElementsHandlerImpl,
+ FixedArray> {
+ public:
+ static MaybeObject* GetWithReceiver(JSObject* obj,
+ Object* receiver,
+ uint32_t index) {
+ FixedArray* parameter_map = GetBackingStore(obj);
+ uint32_t length = parameter_map->length();
+ Object* probe =
+ (index < length - 2) ? parameter_map->get(index + 2) : NULL;
+ if (probe != NULL && !probe->IsTheHole()) {
+ Context* context = Context::cast(parameter_map->get(0));
+ int context_index = Smi::cast(probe)->value();
+ ASSERT(!context->get(context_index)->IsTheHole());
+ return context->get(context_index);
+ } else {
+ // Object is not mapped, defer to the arguments.
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ if (arguments->IsDictionary()) {
+ return DictionaryElementsHandlerImpl::GetNumberDictionaryElement(
+ obj,
+ receiver,
+ NumberDictionary::cast(arguments),
+ index);
+ } else if (index < static_cast<uint32_t>(arguments->length())) {
+ return arguments->get(index);
+ }
+ }
+ return obj->GetHeap()->the_hole_value();
+ }
+};
+
+
+template<typename Impl>
+class ConcreteElementsHandler : public ElementsHandler {
+ public:
+ ConcreteElementsHandler() {}
+
+ virtual MaybeObject* GetWithReceiver(JSObject* obj,
+ Object* receiver,
+ uint32_t index) {
+ return Impl::GetWithReceiver(obj,
+ receiver,
+ index);
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConcreteElementsHandler);
+};
+
+
+struct ConcreteElementHandlers {
Jakob Kummerow 2011/07/30 10:29:21 nit: for consistency, change order to match elemen
danno 2011/07/30 13:10:10 Done.
+ ConcreteElementsHandler<FastElementsHandlerImpl>
+ fast_elements_handler;
+ ConcreteElementsHandler<FastDoubleElementsHandlerImpl>
+ fast_double_elements_handler;
+ ConcreteElementsHandler<ExternalByteElementsHandlerImpl>
+ byte_elements_handler;
+ ConcreteElementsHandler<ExternalUnsignedByteElementsHandlerImpl>
+ unsigned_byte_elements_handler;
+ ConcreteElementsHandler<ExternalShortElementsHandlerImpl>
+ short_elements_handler;
+ ConcreteElementsHandler<ExternalUnsignedShortElementsHandlerImpl>
+ unsigned_short_elements_handler;
+ ConcreteElementsHandler<ExternalIntElementsHandlerImpl>
+ int_elements_handler;
+ ConcreteElementsHandler<ExternalUnsignedIntElementsHandlerImpl>
+ unsigned_int_elements_handler;
+ ConcreteElementsHandler<ExternalFloatElementsHandlerImpl>
+ float_elements_handler;
+ ConcreteElementsHandler<ExternalDoubleElementsHandlerImpl>
+ double_elements_handler;
+ ConcreteElementsHandler<PixelElementsHandlerImpl>
+ pixel_elements_handler;
+ ConcreteElementsHandler<DictionaryElementsHandlerImpl>
+ dictionary_elements_handler;
+ ConcreteElementsHandler<NonStrictArgumentsElementsHandlerImpl>
+ non_strict_arguments_elements_handler;
+} element_handlers;
+
+
+ElementsHandler* ElementsHandler::elements_handler_table_[] = {
+ &element_handlers.fast_elements_handler,
+ &element_handlers.fast_double_elements_handler,
+ &element_handlers.dictionary_elements_handler,
+ &element_handlers.non_strict_arguments_elements_handler,
+ &element_handlers.byte_elements_handler,
+ &element_handlers.unsigned_byte_elements_handler,
+ &element_handlers.short_elements_handler,
+ &element_handlers.unsigned_short_elements_handler,
+ &element_handlers.int_elements_handler,
+ &element_handlers.unsigned_int_elements_handler,
+ &element_handlers.float_elements_handler,
+ &element_handlers.double_elements_handler,
+ &element_handlers.pixel_elements_handler
+};
+
+
+} } // namespace v8::internal
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698