From: vitalyr@chromium.org Date: Wed, 23 Mar 2011 14:44:19 +0000 (+0000) Subject: Store HValue uses in a custom small list structure. X-Git-Tag: upstream/4.7.83~19831 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1dc8f7edb3019a628246ce6fa814fd764291df79;p=platform%2Fupstream%2Fv8.git Store HValue uses in a custom small list structure. This saves about 700K of zone allocation when compiling the V8 benchmark suite. Review URL: http://codereview.chromium.org/6707001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7330 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 7f85bbe..c08540f 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -29,7 +29,9 @@ #define V8_HYDROGEN_INSTRUCTIONS_H_ #include "v8.h" + #include "code-stubs.h" +#include "small-pointer-list.h" #include "string-stream.h" #include "zone.h" @@ -451,7 +453,6 @@ class HValue: public ZoneObject { HValue() : block_(NULL), id_(kNoNumber), - uses_(2), type_(HType::Tagged()), range_(NULL), flags_(0) {} @@ -463,7 +464,7 @@ class HValue: public ZoneObject { int id() const { return id_; } void set_id(int id) { id_ = id; } - ZoneList* uses() { return &uses_; } + SmallPointerList* uses() { return &uses_; } virtual bool EmitAtUses() { return false; } Representation representation() const { return representation_; } @@ -607,7 +608,7 @@ class HValue: public ZoneObject { int id_; Representation representation_; - ZoneList uses_; + SmallPointerList uses_; HType type_; Range* range_; int flags_; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index e9bfafd..28a8908 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -745,7 +745,7 @@ void HGraph::EliminateRedundantPhis() { if (value != NULL) { // Iterate through uses finding the ones that should be // replaced. - ZoneList* uses = phi->uses(); + SmallPointerList* uses = phi->uses(); while (!uses->is_empty()) { HValue* use = uses->RemoveLast(); if (use != NULL) { diff --git a/src/small-pointer-list.h b/src/small-pointer-list.h new file mode 100644 index 0000000..6291d9e --- /dev/null +++ b/src/small-pointer-list.h @@ -0,0 +1,163 @@ +// 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. + +#ifndef V8_SMALL_POINTER_LIST_H_ +#define V8_SMALL_POINTER_LIST_H_ + +#include "checks.h" +#include "v8globals.h" +#include "zone.h" + +namespace v8 { +namespace internal { + +// SmallPointerList is a list optimized for storing no or just a +// single value. When more values are given it falls back to ZoneList. +// +// The interface tries to be as close to List from list.h as possible. +template +class SmallPointerList { + public: + SmallPointerList() : data_(kEmptyTag) {} + + bool is_empty() const { return length() == 0; } + + int length() const { + if ((data_ & kTagMask) == kEmptyTag) return 0; + if ((data_ & kTagMask) == kSingletonTag) return 1; + return list()->length(); + } + + void Add(T* pointer) { + ASSERT(IsAligned(reinterpret_cast(pointer), kPointerAlignment)); + if ((data_ & kTagMask) == kEmptyTag) { + data_ = reinterpret_cast(pointer) | kSingletonTag; + return; + } + if ((data_ & kTagMask) == kSingletonTag) { + PointerList* list = new PointerList(2); + list->Add(single_value()); + list->Add(pointer); + ASSERT(IsAligned(reinterpret_cast(list), kPointerAlignment)); + data_ = reinterpret_cast(list) | kListTag; + return; + } + list()->Add(pointer); + } + + // Note: returns T* and not T*& (unlike List from list.h). + // This makes the implementation simpler and more const correct. + T* at(int i) const { + ASSERT((data_ & kTagMask) != kEmptyTag); + if ((data_ & kTagMask) == kSingletonTag) { + ASSERT(i == 0); + return single_value(); + } + return list()->at(i); + } + + // See the note above. + T* operator[](int i) const { return at(i); } + + // Remove the given element from the list (if present). + void RemoveElement(T* pointer) { + if ((data_ & kTagMask) == kEmptyTag) return; + if ((data_ & kTagMask) == kSingletonTag) { + if (pointer == single_value()) { + data_ = kEmptyTag; + } + return; + } + list()->RemoveElement(pointer); + } + + T* RemoveLast() { + ASSERT((data_ & kTagMask) != kEmptyTag); + if ((data_ & kTagMask) == kSingletonTag) { + T* result = single_value(); + data_ = kEmptyTag; + return result; + } + return list()->RemoveLast(); + } + + void Rewind(int pos) { + if ((data_ & kTagMask) == kEmptyTag) { + ASSERT(pos == 0); + return; + } + if ((data_ & kTagMask) == kSingletonTag) { + ASSERT(pos == 0 || pos == 1); + if (pos == 0) { + data_ = kEmptyTag; + } + return; + } + list()->Rewind(pos); + } + + int CountOccurrences(T* pointer, int start, int end) const { + if ((data_ & kTagMask) == kEmptyTag) return 0; + if ((data_ & kTagMask) == kSingletonTag) { + if (start == 0 && end >= 0) { + return (single_value() == pointer) ? 1 : 0; + } + return 0; + } + return list()->CountOccurrences(pointer, start, end); + } + + private: + typedef ZoneList PointerList; + + static const intptr_t kEmptyTag = 1; + static const intptr_t kSingletonTag = 0; + static const intptr_t kListTag = 2; + static const intptr_t kTagMask = 3; + static const intptr_t kValueMask = ~kTagMask; + + STATIC_ASSERT(kTagMask + 1 <= kPointerAlignment); + + T* single_value() const { + ASSERT((data_ & kTagMask) == kSingletonTag); + STATIC_ASSERT(kSingletonTag == 0); + return reinterpret_cast(data_); + } + + PointerList* list() const { + ASSERT((data_ & kTagMask) == kListTag); + return reinterpret_cast(data_ & kValueMask); + } + + intptr_t data_; + + DISALLOW_COPY_AND_ASSIGN(SmallPointerList); +}; + +} } // namespace v8::internal + +#endif // V8_SMALL_POINTER_LIST_H_ diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index e82b098..4d27bc0 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -512,6 +512,7 @@ '../../src/serialize.cc', '../../src/serialize.h', '../../src/shell.h', + '../../src/small-pointer-list.h', '../../src/smart-pointer.h', '../../src/snapshot-common.cc', '../../src/snapshot.h', diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj index f7eafbd..560b035 100644 --- a/tools/v8.xcodeproj/project.pbxproj +++ b/tools/v8.xcodeproj/project.pbxproj @@ -914,6 +914,7 @@ 89F3605A12DCDF6400ACF8A6 /* lithium-codegen-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-codegen-x64.cc"; path = "x64/lithium-codegen-x64.cc"; sourceTree = ""; }; 89FB0E360F8E531900B04B3C /* d8-posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-posix.cc"; path = "../src/d8-posix.cc"; sourceTree = ""; }; 89FB0E370F8E531900B04B3C /* d8-windows.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-windows.cc"; path = "../src/d8-windows.cc"; sourceTree = ""; }; + 9C1F8E1D133906180068B362 /* small-pointer-list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "small-pointer-list.h"; sourceTree = ""; }; 9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "heap-profiler.cc"; sourceTree = ""; }; 9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "heap-profiler.h"; sourceTree = ""; }; 9F2B370E114FF62D007CDAF4 /* circular-queue-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "circular-queue-inl.h"; sourceTree = ""; }; @@ -1283,6 +1284,7 @@ 897FF17B0E719B8F00D62E90 /* serialize.h */, 897FF17C0E719B8F00D62E90 /* shell.h */, 893E24A012B14B3D0083370F /* simulator.h */, + 9C1F8E1D133906180068B362 /* small-pointer-list.h */, 897FF1810E719B8F00D62E90 /* smart-pointer.h */, 897FF1820E719B8F00D62E90 /* snapshot-common.cc */, 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */, diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj index 0156616..9c2e355 100644 --- a/tools/visual_studio/v8_base.vcproj +++ b/tools/visual_studio/v8_base.vcproj @@ -1026,6 +1026,10 @@ > + + diff --git a/tools/visual_studio/v8_base_arm.vcproj b/tools/visual_studio/v8_base_arm.vcproj index 6ae962c..87c178a 100644 --- a/tools/visual_studio/v8_base_arm.vcproj +++ b/tools/visual_studio/v8_base_arm.vcproj @@ -984,6 +984,10 @@ > + + diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj index dc2167b..de921bc 100644 --- a/tools/visual_studio/v8_base_x64.vcproj +++ b/tools/visual_studio/v8_base_x64.vcproj @@ -1026,6 +1026,10 @@ > + +