|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "tonic/dart_string_cache.h" | 
|  |  | 
|  | #include "tonic/dart_state.h" | 
|  | #include "tonic/dart_string.h" | 
|  |  | 
|  | namespace tonic { | 
|  |  | 
|  | DartStringCache::DartStringCache() : last_dart_string_(nullptr) { | 
|  | } | 
|  |  | 
|  | DartStringCache::~DartStringCache() { | 
|  | } | 
|  |  | 
|  | Dart_WeakPersistentHandle DartStringCache::GetSlow(StringImpl* string_impl, | 
|  | bool auto_scope) { | 
|  | if (Dart_WeakPersistentHandle string = cache_.get(string_impl)) { | 
|  | last_dart_string_ = string; | 
|  | last_string_impl_ = string_impl; | 
|  | return string; | 
|  | } | 
|  |  | 
|  | if (!auto_scope) | 
|  | Dart_EnterScope(); | 
|  |  | 
|  | Dart_Handle string = CreateDartString(string_impl); | 
|  | DCHECK(!Dart_IsError(string)); | 
|  |  | 
|  | intptr_t size_in_bytes = string_impl->sizeInBytes(); | 
|  | Dart_WeakPersistentHandle wrapper = Dart_NewWeakPersistentHandle( | 
|  | string, string_impl, size_in_bytes, FinalizeCacheEntry); | 
|  |  | 
|  | string_impl->ref();  // Balanced in FinalizeCacheEntry. | 
|  | cache_.set(string_impl, wrapper); | 
|  |  | 
|  | last_dart_string_ = wrapper; | 
|  | last_string_impl_ = string_impl; | 
|  |  | 
|  | if (!auto_scope) | 
|  | Dart_ExitScope(); | 
|  |  | 
|  | return wrapper; | 
|  | } | 
|  |  | 
|  | void DartStringCache::FinalizeCacheEntry(void* isolate_callback_data, | 
|  | Dart_WeakPersistentHandle handle, | 
|  | void* peer) { | 
|  | DartState* state = reinterpret_cast<DartState*>(isolate_callback_data); | 
|  | StringImpl* string_impl = reinterpret_cast<StringImpl*>(peer); | 
|  | DartStringCache& cache = state->string_cache(); | 
|  |  | 
|  | Dart_WeakPersistentHandle cached_handle = cache.cache_.take(string_impl); | 
|  | ASSERT_UNUSED(cached_handle, handle == cached_handle); | 
|  |  | 
|  | if (cache.last_dart_string_ == handle) { | 
|  | cache.last_dart_string_ = nullptr; | 
|  | cache.last_string_impl_ = nullptr; | 
|  | } | 
|  |  | 
|  | string_impl->deref(); | 
|  | } | 
|  |  | 
|  | }  // namespace tonic |