lookup-cache.h revision f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3
1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_LOOKUP_CACHE_H_
6#define V8_LOOKUP_CACHE_H_
7
8#include "src/objects.h"
9
10namespace v8 {
11namespace internal {
12
13// Cache for mapping (map, property name) into descriptor index.
14// The cache contains both positive and negative results.
15// Descriptor index equals kNotFound means the property is absent.
16// Cleared at startup and prior to any gc.
17class DescriptorLookupCache {
18 public:
19  // Lookup descriptor index for (map, name).
20  // If absent, kAbsent is returned.
21  inline int Lookup(Map* source, Name* name);
22
23  // Update an element in the cache.
24  inline void Update(Map* source, Name* name, int result);
25
26  // Clear the cache.
27  void Clear();
28
29  static const int kAbsent = -2;
30
31 private:
32  DescriptorLookupCache() {
33    for (int i = 0; i < kLength; ++i) {
34      keys_[i].source = NULL;
35      keys_[i].name = NULL;
36      results_[i] = kAbsent;
37    }
38  }
39
40  static inline int Hash(Object* source, Name* name);
41
42  static const int kLength = 64;
43  struct Key {
44    Map* source;
45    Name* name;
46  };
47
48  Key keys_[kLength];
49  int results_[kLength];
50
51  friend class Isolate;
52  DISALLOW_COPY_AND_ASSIGN(DescriptorLookupCache);
53};
54
55// Cache for mapping (map, property name) into field offset.
56// Cleared at startup and prior to mark sweep collection.
57class KeyedLookupCache {
58 public:
59  // Lookup field offset for (map, name). If absent, -1 is returned.
60  int Lookup(Handle<Map> map, Handle<Name> name);
61
62  // Update an element in the cache.
63  void Update(Handle<Map> map, Handle<Name> name, int field_offset);
64
65  // Clear the cache.
66  void Clear();
67
68  static const int kLength = 256;
69  static const int kCapacityMask = kLength - 1;
70  static const int kMapHashShift = 5;
71  static const int kHashMask = -4;  // Zero the last two bits.
72  static const int kEntriesPerBucket = 4;
73  static const int kEntryLength = 2;
74  static const int kMapIndex = 0;
75  static const int kKeyIndex = 1;
76  static const int kNotFound = -1;
77
78  // kEntriesPerBucket should be a power of 2.
79  STATIC_ASSERT((kEntriesPerBucket & (kEntriesPerBucket - 1)) == 0);
80  STATIC_ASSERT(kEntriesPerBucket == -kHashMask);
81
82 private:
83  KeyedLookupCache() {
84    for (int i = 0; i < kLength; ++i) {
85      keys_[i].map = NULL;
86      keys_[i].name = NULL;
87      field_offsets_[i] = kNotFound;
88    }
89  }
90
91  static inline int Hash(Handle<Map> map, Handle<Name> name);
92
93  // Get the address of the keys and field_offsets arrays.  Used in
94  // generated code to perform cache lookups.
95  Address keys_address() { return reinterpret_cast<Address>(&keys_); }
96
97  Address field_offsets_address() {
98    return reinterpret_cast<Address>(&field_offsets_);
99  }
100
101  struct Key {
102    Map* map;
103    Name* name;
104  };
105
106  Key keys_[kLength];
107  int field_offsets_[kLength];
108
109  friend class ExternalReference;
110  friend class Isolate;
111  DISALLOW_COPY_AND_ASSIGN(KeyedLookupCache);
112};
113
114}  // namespace internal
115}  // namespace v8
116
117#endif  // V8_LOOKUP_CACHE_H_
118