intern_table.h revision 94f7b49578b6aaa80de8ffed230648d601393905
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_INTERN_TABLE_H_
18#define ART_RUNTIME_INTERN_TABLE_H_
19
20#include <map>
21
22#include "base/mutex.h"
23#include "gc_root.h"
24#include "object_callbacks.h"
25
26namespace art {
27
28enum VisitRootFlags : uint8_t;
29
30namespace mirror {
31class String;
32}  // namespace mirror
33class Transaction;
34
35/**
36 * Used to intern strings.
37 *
38 * There are actually two tables: one that holds strong references to its strings, and one that
39 * holds weak references. The former is used for string literals, for which there is an effective
40 * reference from the constant pool. The latter is used for strings interned at runtime via
41 * String.intern. Some code (XML parsers being a prime example) relies on being able to intern
42 * arbitrarily many strings for the duration of a parse without permanently increasing the memory
43 * footprint.
44 */
45class InternTable {
46 public:
47  InternTable();
48
49  // Interns a potentially new string in the 'strong' table. (See above.)
50  mirror::String* InternStrong(int32_t utf16_length, const char* utf8_data)
51      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
52
53  // Interns a potentially new string in the 'strong' table. (See above.)
54  mirror::String* InternStrong(const char* utf8_data)
55      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
56
57  // Interns a potentially new string in the 'strong' table. (See above.)
58  mirror::String* InternStrong(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
59
60  // Interns a potentially new string in the 'weak' table. (See above.)
61  mirror::String* InternWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
62
63  void SweepInternTableWeaks(IsMarkedCallback* callback, void* arg)
64      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
65
66  bool ContainsWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
67
68  size_t Size() const;
69  size_t StrongSize() const;
70  size_t WeakSize() const;
71
72  void VisitRoots(RootCallback* callback, void* arg, VisitRootFlags flags)
73      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
74
75  void DumpForSigQuit(std::ostream& os) const;
76
77  void DisallowNewInterns() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
78  void AllowNewInterns() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
79
80 private:
81  typedef std::multimap<int32_t, GcRoot<mirror::String>> Table;
82
83  mirror::String* Insert(mirror::String* s, bool is_strong)
84      LOCKS_EXCLUDED(Locks::intern_table_lock_)
85      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
86
87  mirror::String* LookupStrong(mirror::String* s, int32_t hash_code)
88      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
89  mirror::String* LookupWeak(mirror::String* s, int32_t hash_code)
90      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
91  mirror::String* Lookup(Table* table, mirror::String* s, int32_t hash_code)
92      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
93  mirror::String* InsertStrong(mirror::String* s, int32_t hash_code)
94      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
95  mirror::String* InsertWeak(mirror::String* s, int32_t hash_code)
96      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
97  void RemoveStrong(mirror::String* s, int32_t hash_code)
98      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
99      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
100  void RemoveWeak(mirror::String* s, int32_t hash_code)
101      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
102      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
103  void Remove(Table* table, mirror::String* s, int32_t hash_code)
104      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
105      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
106
107  // Transaction rollback access.
108  mirror::String* InsertStrongFromTransaction(mirror::String* s, int32_t hash_code)
109      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
110  mirror::String* InsertWeakFromTransaction(mirror::String* s, int32_t hash_code)
111      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
112  void RemoveStrongFromTransaction(mirror::String* s, int32_t hash_code)
113      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
114      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
115  void RemoveWeakFromTransaction(mirror::String* s, int32_t hash_code)
116      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
117      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
118  friend class Transaction;
119
120  bool log_new_roots_ GUARDED_BY(Locks::intern_table_lock_);
121  bool allow_new_interns_ GUARDED_BY(Locks::intern_table_lock_);
122  ConditionVariable new_intern_condition_ GUARDED_BY(Locks::intern_table_lock_);
123  // Since this contains (strong) roots, they need a read barrier to
124  // enable concurrent intern table (strong) root scan. Do not
125  // directly access the strings in it. Use functions that contain
126  // read barriers.
127  Table strong_interns_ GUARDED_BY(Locks::intern_table_lock_);
128  std::vector<std::pair<int32_t, GcRoot<mirror::String>>> new_strong_intern_roots_
129      GUARDED_BY(Locks::intern_table_lock_);
130  // Since this contains (weak) roots, they need a read barrier. Do
131  // not directly access the strings in it. Use functions that contain
132  // read barriers.
133  Table weak_interns_ GUARDED_BY(Locks::intern_table_lock_);
134};
135
136}  // namespace art
137
138#endif  // ART_RUNTIME_INTERN_TABLE_H_
139