blob: 73a77b425850bb7f503e9f354bb882db714dbf80 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
Carl Shapiro69759ea2011-07-21 18:13:35 -070016
17#ifndef ART_SRC_MARK_STACK_H_
18#define ART_SRC_MARK_STACK_H_
19
Mathieu Chartier357e9be2012-08-01 11:00:14 -070020#include <string>
21
22#include "atomic.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070023#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070024#include "logging.h"
25#include "macros.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070026#include "mem_map.h"
Carl Shapiro69759ea2011-07-21 18:13:35 -070027
28namespace art {
29
30class Object;
31
32class MarkStack {
33 public:
Mathieu Chartier357e9be2012-08-01 11:00:14 -070034 // Length is in bytes.
35 static MarkStack* Create(const std::string& name, size_t length);
Carl Shapiro69759ea2011-07-21 18:13:35 -070036
37 ~MarkStack();
38
39 void Push(const Object* obj) {
40 DCHECK(obj != NULL);
41 DCHECK_NE(ptr_, limit_);
42 *ptr_ = obj;
43 ++ptr_;
44 }
45
Mathieu Chartier357e9be2012-08-01 11:00:14 -070046 // Beware: Atomic pushes and pops don't mix well.
47 void AtomicPush(const Object* obj) {
48 DCHECK(obj != NULL);
49 DCHECK_NE(ptr_, limit_);
50 DCHECK_EQ(sizeof(ptr_), sizeof(int32_t));
51 int32_t* ptr = reinterpret_cast<int32_t*>(&ptr_);
52 *reinterpret_cast<const Object**>(android_atomic_add(sizeof(*ptr_), ptr)) = obj;
53 }
54
Carl Shapiro69759ea2011-07-21 18:13:35 -070055 const Object* Pop() {
Ian Rogers30fab402012-01-23 15:43:46 -080056 DCHECK_NE(ptr_, begin_);
Carl Shapiro69759ea2011-07-21 18:13:35 -070057 --ptr_;
58 DCHECK(*ptr_ != NULL);
59 return *ptr_;
60 }
61
62 bool IsEmpty() const {
Ian Rogers30fab402012-01-23 15:43:46 -080063 return ptr_ == begin_;
Carl Shapiro69759ea2011-07-21 18:13:35 -070064 }
65
Mathieu Chartier357e9be2012-08-01 11:00:14 -070066 size_t Size() const {
67 DCHECK_GE(ptr_, begin_);
68 return ptr_ - begin_;
69 }
70
71 const Object* Get(size_t index) const {
72 DCHECK_LT(index, Size());
73 return begin_[index];
74 }
75
76 Object** Begin() {
77 return const_cast<Object**>(begin_);
78 }
79
Mathieu Chartier5301cd22012-05-31 12:11:36 -070080 void Reset();
81
Carl Shapiro69759ea2011-07-21 18:13:35 -070082 private:
Mathieu Chartier357e9be2012-08-01 11:00:14 -070083 MarkStack(const std::string& name) : name_(name), begin_(NULL), limit_(NULL), ptr_(NULL) {}
Carl Shapiro69759ea2011-07-21 18:13:35 -070084
Mathieu Chartier357e9be2012-08-01 11:00:14 -070085 void Init(size_t length);
86
87 // Name of the mark stack.
88 const std::string& name_;
Carl Shapiro69759ea2011-07-21 18:13:35 -070089
Brian Carlstromdb4d5402011-08-09 12:18:28 -070090 // Memory mapping of the mark stack.
Elliott Hughes90a33692011-08-30 13:27:07 -070091 UniquePtr<MemMap> mem_map_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070092
Carl Shapiro69759ea2011-07-21 18:13:35 -070093 // Base of the mark stack.
Ian Rogers30fab402012-01-23 15:43:46 -080094 const Object* const* begin_;
Carl Shapiro69759ea2011-07-21 18:13:35 -070095
96 // Exclusive limit of the mark stack.
97 const Object* const* limit_;
98
99 // Pointer to the top of the mark stack.
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700100 const Object** ptr_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700101
102 DISALLOW_COPY_AND_ASSIGN(MarkStack);
103};
104
105} // namespace art
106
107#endif // ART_SRC_MARK_STACK_H_