diff options
Diffstat (limited to 'chromium/v8/src/field-index.h')
-rw-r--r-- | chromium/v8/src/field-index.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/chromium/v8/src/field-index.h b/chromium/v8/src/field-index.h new file mode 100644 index 00000000000..0f77c8c57e4 --- /dev/null +++ b/chromium/v8/src/field-index.h @@ -0,0 +1,119 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_FIELD_INDEX_H_ +#define V8_FIELD_INDEX_H_ + +#include "src/utils.h" +#include "src/property-details.h" + +namespace v8 { +namespace internal { + +class Map; + +// Wrapper class to hold a field index, usually but not necessarily generated +// from a property index. When available, the wrapper class captures additional +// information to allow the field index to be translated back into the property +// index it was originally generated from. +class FieldIndex V8_FINAL { + public: + static FieldIndex ForPropertyIndex(Map* map, + int index, + bool is_double = false); + static FieldIndex ForInObjectOffset(int offset, Map* map = NULL); + static FieldIndex ForLookupResult(const LookupResult* result); + static FieldIndex ForDescriptor(Map* map, int descriptor_index); + static FieldIndex ForLoadByFieldIndex(Map* map, int index); + static FieldIndex ForKeyedLookupCacheIndex(Map* map, int index); + + bool is_inobject() const { + return IsInObjectBits::decode(bit_field_); + } + + bool is_double() const { + return IsDoubleBits::decode(bit_field_); + } + + int offset() const { + return index() * kPointerSize; + } + + int index() const { + return IndexBits::decode(bit_field_); + } + + int outobject_array_index() const { + ASSERT(!is_inobject()); + return index() - first_inobject_property_offset() / kPointerSize; + } + + int property_index() const { + ASSERT(!IsHiddenField::decode(bit_field_)); + int result = index() - first_inobject_property_offset() / kPointerSize; + if (!is_inobject()) { + result += InObjectPropertyBits::decode(bit_field_); + } + return result; + } + + int GetLoadByFieldIndex() const { + // For efficiency, the LoadByFieldIndex instruction takes an index that is + // optimized for quick access. If the property is inline, the index is + // positive. If it's out-of-line, the encoded index is -raw_index - 1 to + // disambiguate the zero out-of-line index from the zero inobject case. + // The index itself is shifted up by one bit, the lower-most bit + // signifying if the field is a mutable double box (1) or not (0). + int result = index() - first_inobject_property_offset() / kPointerSize; + if (!is_inobject()) { + result = -result - 1; + } + result <<= 1; + return is_double() ? (result | 1) : result; + } + + int GetKeyedLookupCacheIndex() const; + + int GetLoadFieldStubKey() const { + return bit_field_ & + (IsInObjectBits::kMask | IsDoubleBits::kMask | IndexBits::kMask); + } + + private: + FieldIndex(bool is_inobject, int local_index, bool is_double, + int inobject_properties, int first_inobject_property_offset, + bool is_hidden = false) { + ASSERT((first_inobject_property_offset & (kPointerSize - 1)) == 0); + bit_field_ = IsInObjectBits::encode(is_inobject) | + IsDoubleBits::encode(is_double) | + FirstInobjectPropertyOffsetBits::encode(first_inobject_property_offset) | + IsHiddenField::encode(is_hidden) | + IndexBits::encode(local_index) | + InObjectPropertyBits::encode(inobject_properties); + } + + int first_inobject_property_offset() const { + ASSERT(!IsHiddenField::decode(bit_field_)); + return FirstInobjectPropertyOffsetBits::decode(bit_field_); + } + + static const int kIndexBitsSize = kDescriptorIndexBitCount + 1; + + class IndexBits: public BitField<int, 0, kIndexBitsSize> {}; + class IsInObjectBits: public BitField<bool, IndexBits::kNext, 1> {}; + class IsDoubleBits: public BitField<bool, IsInObjectBits::kNext, 1> {}; + class InObjectPropertyBits: public BitField<int, IsDoubleBits::kNext, + kDescriptorIndexBitCount> {}; + class FirstInobjectPropertyOffsetBits: + public BitField<int, InObjectPropertyBits::kNext, 7> {}; + class IsHiddenField: + public BitField<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {}; + STATIC_ASSERT(IsHiddenField::kNext <= 32); + + int bit_field_; +}; + +} } // namespace v8::internal + +#endif |