1// Copyright 2018 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_OBJECTS_PROTOTYPE_INFO_H_
6#define V8_OBJECTS_PROTOTYPE_INFO_H_
7
8#include "src/objects.h"
9#include "src/objects/fixed-array.h"
10#include "src/objects/struct.h"
11
12// Has to be the last include (doesn't have include guards):
13#include "src/objects/object-macros.h"
14
15namespace v8 {
16namespace internal {
17
18// Container for metadata stored on each prototype map.
19class PrototypeInfo : public Struct {
20 public:
21 static const int UNREGISTERED = -1;
22
23 // [module_namespace]: A backpointer to JSModuleNamespace from its
24 // PrototypeInfo (or undefined). This field is only used for JSModuleNamespace
25 // maps. TODO(jkummerow): Figure out if there's a way to store the namespace
26 // pointer elsewhere to save memory.
27 DECL_ACCESSORS(module_namespace, Object)
28
29 // [prototype_users]: WeakArrayList containing weak references to maps using
30 // this prototype, or Smi(0) if uninitialized.
31 DECL_ACCESSORS(prototype_users, Object)
32
33 // [object_create_map]: A field caching the map for Object.create(prototype).
34 static inline void SetObjectCreateMap(Handle<PrototypeInfo> info,
35 Handle<Map> map);
36 inline Map ObjectCreateMap();
37 inline bool HasObjectCreateMap();
38
39 // [registry_slot]: Slot in prototype's user registry where this user
40 // is stored. Returns UNREGISTERED if this prototype has not been registered.
41 inline int registry_slot() const;
42 inline void set_registry_slot(int slot);
43
44 // [bit_field]
45 inline int bit_field() const;
46 inline void set_bit_field(int bit_field);
47
48 DECL_BOOLEAN_ACCESSORS(should_be_fast_map)
49
50 DECL_CAST(PrototypeInfo)
51
52 // Dispatched behavior.
53 DECL_PRINTER(PrototypeInfo)
54 DECL_VERIFIER(PrototypeInfo)
55
56 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
57 TORQUE_GENERATED_PROTOTYPE_INFO_FIELDS)
58
59 // Bit field usage.
60 static const int kShouldBeFastBit = 0;
61
62 class BodyDescriptor;
63
64 private:
65 DECL_ACCESSORS(object_create_map, MaybeObject)
66
67 OBJECT_CONSTRUCTORS(PrototypeInfo, Struct);
68};
69
70// A growing array with an additional API for marking slots "empty". When adding
71// new elements, we reuse the empty slots instead of growing the array.
72class V8_EXPORT_PRIVATE PrototypeUsers : public WeakArrayList {
73 public:
74 static Handle<WeakArrayList> Add(Isolate* isolate,
75 Handle<WeakArrayList> array,
76 Handle<Map> value, int* assigned_index);
77
78 static inline void MarkSlotEmpty(WeakArrayList array, int index);
79
80 // The callback is called when a weak pointer to HeapObject "object" is moved
81 // from index "from_index" to index "to_index" during compaction. The callback
82 // must not cause GC.
83 using CompactionCallback = void (*)(HeapObject object, int from_index,
84 int to_index);
85 static WeakArrayList Compact(
86 Handle<WeakArrayList> array, Heap* heap, CompactionCallback callback,
87 AllocationType allocation = AllocationType::kYoung);
88
89#ifdef VERIFY_HEAP
90 static void Verify(WeakArrayList array);
91#endif // VERIFY_HEAP
92
93 static const int kEmptySlotIndex = 0;
94 static const int kFirstIndex = 1;
95
96 static const int kNoEmptySlotsMarker = 0;
97
98 private:
99 static inline Smi empty_slot_index(WeakArrayList array);
100 static inline void set_empty_slot_index(WeakArrayList array, int index);
101
102 static void IsSlotEmpty(WeakArrayList array, int index);
103
104 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeUsers);
105};
106
107} // namespace internal
108} // namespace v8
109
110#include "src/objects/object-macros-undef.h"
111
112#endif // V8_OBJECTS_PROTOTYPE_INFO_H_
113