intern_table.h revision 893263b7d5bc2ca43a91ecb8071867f5134fc60a
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 "base/mutex.h"
21#include "locks.h"
22#include "object_callbacks.h"
23
24#include <map>
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
65  bool ContainsWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
66
67  size_t Size() const;
68
69  void VisitRoots(RootCallback* callback, void* arg, VisitRootFlags flags);
70
71  void DumpForSigQuit(std::ostream& os) const;
72
73  void DisallowNewInterns() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
74  void AllowNewInterns() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
75
76 private:
77  typedef std::multimap<int32_t, mirror::String*> Table;
78
79  mirror::String* Insert(mirror::String* s, bool is_strong)
80      LOCKS_EXCLUDED(Locks::intern_table_lock_)
81      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
82
83  mirror::String* Lookup(Table& table, mirror::String* s, int32_t hash_code)
84      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
85  mirror::String* InsertStrong(mirror::String* s, int32_t hash_code)
86      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
87  mirror::String* InsertWeak(mirror::String* s, int32_t hash_code)
88      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
89  void RemoveWeak(mirror::String* s, int32_t hash_code)
90      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
91  void Remove(Table& table, mirror::String* s, int32_t hash_code)
92      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
93
94  // Transaction rollback access.
95  mirror::String* InsertStrongFromTransaction(mirror::String* s, int32_t hash_code)
96      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
97  mirror::String* InsertWeakFromTransaction(mirror::String* s, int32_t hash_code)
98      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
99  void RemoveStrongFromTransaction(mirror::String* s, int32_t hash_code)
100      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
101  void RemoveWeakFromTransaction(mirror::String* s, int32_t hash_code)
102      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
103  friend class Transaction;
104
105  bool log_new_roots_ GUARDED_BY(Locks::intern_table_lock_);
106  bool allow_new_interns_ GUARDED_BY(Locks::intern_table_lock_);
107  ConditionVariable new_intern_condition_ GUARDED_BY(Locks::intern_table_lock_);
108  Table strong_interns_ GUARDED_BY(Locks::intern_table_lock_);
109  std::vector<std::pair<int32_t, mirror::String*> > new_strong_intern_roots_
110      GUARDED_BY(Locks::intern_table_lock_);
111  Table weak_interns_ GUARDED_BY(Locks::intern_table_lock_);
112};
113
114}  // namespace art
115
116#endif  // ART_RUNTIME_INTERN_TABLE_H_
117