summaryrefslogtreecommitdiff
path: root/src/mark_stack.cc
blob: e1aa6161d3c865ecf4f88ce0d00a01ab5e98d556 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mark_stack.h"

#include "globals.h"
#include "logging.h"
#include "UniquePtr.h"
#include "utils.h"

namespace art {

MarkStack* MarkStack::Create() {
  UniquePtr<MarkStack> mark_stack(new MarkStack);
  mark_stack->Init();
  return mark_stack.release();
}

void MarkStack::Init() {
  size_t length = 64 * MB;
  mem_map_.reset(MemMap::MapAnonymous("dalvik-mark-stack", NULL, length, PROT_READ | PROT_WRITE));
  if (mem_map_.get() == NULL) {
    std::string maps;
    ReadFileToString("/proc/self/maps", &maps);
    LOG(FATAL) << "couldn't allocate mark stack\n" << maps;
  }
  byte* addr = mem_map_->Begin();
  CHECK(addr != NULL);

  begin_ = reinterpret_cast<const Object**>(addr);
  limit_ = reinterpret_cast<const Object**>(addr + length);

  Reset();
}

void MarkStack::Reset() {
  DCHECK(mem_map_.get() != NULL);
  DCHECK(begin_ != NULL);
  DCHECK(limit_ != NULL);
  byte* addr = const_cast<byte*>(reinterpret_cast<const byte*>(begin_));
  const size_t length = limit_ - begin_;
  ptr_ = reinterpret_cast<const Object**>(addr);
  int result = madvise(addr, length, MADV_DONTNEED);
  if (result == -1) {
    PLOG(WARNING) << "madvise failed";
  }
}

MarkStack::~MarkStack() {
  CHECK(IsEmpty());
}

}  // namespace art