11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/handles/local-handles.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/api/api.h"
81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
91cb0ef41Sopenharmony_ci#include "src/handles/handles-inl.h"
101cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
111cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciAddress* LocalHandleScope::GetMainThreadHandle(LocalHeap* local_heap,
171cb0ef41Sopenharmony_ci                                               Address value) {
181cb0ef41Sopenharmony_ci  Isolate* isolate = local_heap->heap()->isolate();
191cb0ef41Sopenharmony_ci  return HandleScope::GetHandle(isolate, value);
201cb0ef41Sopenharmony_ci}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_civoid LocalHandleScope::OpenMainThreadScope(LocalHeap* local_heap) {
231cb0ef41Sopenharmony_ci  Isolate* isolate = local_heap->heap()->isolate();
241cb0ef41Sopenharmony_ci  HandleScopeData* data = isolate->handle_scope_data();
251cb0ef41Sopenharmony_ci  local_heap_ = local_heap;
261cb0ef41Sopenharmony_ci  prev_next_ = data->next;
271cb0ef41Sopenharmony_ci  prev_limit_ = data->limit;
281cb0ef41Sopenharmony_ci  data->level++;
291cb0ef41Sopenharmony_ci}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_civoid LocalHandleScope::CloseMainThreadScope(LocalHeap* local_heap,
321cb0ef41Sopenharmony_ci                                            Address* prev_next,
331cb0ef41Sopenharmony_ci                                            Address* prev_limit) {
341cb0ef41Sopenharmony_ci  Isolate* isolate = local_heap->heap()->isolate();
351cb0ef41Sopenharmony_ci  HandleScope::CloseScope(isolate, prev_next, prev_limit);
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciLocalHandles::LocalHandles() { scope_.Initialize(); }
391cb0ef41Sopenharmony_ciLocalHandles::~LocalHandles() {
401cb0ef41Sopenharmony_ci  scope_.limit = nullptr;
411cb0ef41Sopenharmony_ci  RemoveUnusedBlocks();
421cb0ef41Sopenharmony_ci  DCHECK(blocks_.empty());
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_civoid LocalHandles::Iterate(RootVisitor* visitor) {
461cb0ef41Sopenharmony_ci  for (int i = 0; i < static_cast<int>(blocks_.size()) - 1; i++) {
471cb0ef41Sopenharmony_ci    Address* block = blocks_[i];
481cb0ef41Sopenharmony_ci    visitor->VisitRootPointers(Root::kHandleScope, nullptr,
491cb0ef41Sopenharmony_ci                               FullObjectSlot(block),
501cb0ef41Sopenharmony_ci                               FullObjectSlot(&block[kHandleBlockSize]));
511cb0ef41Sopenharmony_ci  }
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  if (!blocks_.empty()) {
541cb0ef41Sopenharmony_ci    Address* block = blocks_.back();
551cb0ef41Sopenharmony_ci    visitor->VisitRootPointers(Root::kHandleScope, nullptr,
561cb0ef41Sopenharmony_ci                               FullObjectSlot(block),
571cb0ef41Sopenharmony_ci                               FullObjectSlot(scope_.next));
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci#ifdef DEBUG
621cb0ef41Sopenharmony_cibool LocalHandles::Contains(Address* location) {
631cb0ef41Sopenharmony_ci  // We have to search in all blocks since they have no guarantee of order.
641cb0ef41Sopenharmony_ci  for (auto it = blocks_.begin(); it != blocks_.end(); ++it) {
651cb0ef41Sopenharmony_ci    Address* lower_bound = *it;
661cb0ef41Sopenharmony_ci    // The last block is a special case because it may have less than
671cb0ef41Sopenharmony_ci    // block_size_ handles.
681cb0ef41Sopenharmony_ci    Address* upper_bound = lower_bound != blocks_.back()
691cb0ef41Sopenharmony_ci                               ? lower_bound + kHandleBlockSize
701cb0ef41Sopenharmony_ci                               : scope_.next;
711cb0ef41Sopenharmony_ci    if (lower_bound <= location && location < upper_bound) {
721cb0ef41Sopenharmony_ci      return true;
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci  }
751cb0ef41Sopenharmony_ci  return false;
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci#endif
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciAddress* LocalHandles::AddBlock() {
801cb0ef41Sopenharmony_ci  DCHECK_EQ(scope_.next, scope_.limit);
811cb0ef41Sopenharmony_ci  Address* block = NewArray<Address>(kHandleBlockSize);
821cb0ef41Sopenharmony_ci  blocks_.push_back(block);
831cb0ef41Sopenharmony_ci  scope_.next = block;
841cb0ef41Sopenharmony_ci  scope_.limit = block + kHandleBlockSize;
851cb0ef41Sopenharmony_ci  return block;
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_civoid LocalHandles::RemoveUnusedBlocks() {
891cb0ef41Sopenharmony_ci  while (!blocks_.empty()) {
901cb0ef41Sopenharmony_ci    Address* block_start = blocks_.back();
911cb0ef41Sopenharmony_ci    Address* block_limit = block_start + kHandleBlockSize;
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci    if (block_limit == scope_.limit) {
941cb0ef41Sopenharmony_ci      break;
951cb0ef41Sopenharmony_ci    }
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci    blocks_.pop_back();
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci#ifdef ENABLE_HANDLE_ZAPPING
1001cb0ef41Sopenharmony_ci    ZapRange(block_start, block_limit);
1011cb0ef41Sopenharmony_ci#endif
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci    DeleteArray(block_start);
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci}
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci#ifdef ENABLE_HANDLE_ZAPPING
1081cb0ef41Sopenharmony_civoid LocalHandles::ZapRange(Address* start, Address* end) {
1091cb0ef41Sopenharmony_ci  HandleScope::ZapRange(start, end);
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci#endif
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci}  // namespace internal
1141cb0ef41Sopenharmony_ci}  // namespace v8
115