|  | // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | #include "vm/code_observers.h" | 
|  |  | 
|  | #include "vm/os.h" | 
|  | #include "vm/os_thread.h" | 
|  |  | 
|  | namespace dart { | 
|  |  | 
|  | #ifndef PRODUCT | 
|  |  | 
|  | Mutex* CodeObservers::mutex_ = nullptr; | 
|  | intptr_t CodeObservers::observers_length_ = 0; | 
|  | CodeObserver** CodeObservers::observers_ = nullptr; | 
|  |  | 
|  | class ExternalCodeObserverAdapter : public CodeObserver { | 
|  | public: | 
|  | explicit ExternalCodeObserverAdapter(Dart_CodeObserver delegate) | 
|  | : delegate_(delegate) {} | 
|  |  | 
|  | virtual bool IsActive() const { return true; } | 
|  |  | 
|  | virtual void Notify(const char* name, | 
|  | uword base, | 
|  | uword prologue_offset, | 
|  | uword size, | 
|  | bool optimized, | 
|  | const CodeComments* comments) { | 
|  | return delegate_.on_new_code(&delegate_, name, base, size); | 
|  | } | 
|  |  | 
|  | private: | 
|  | Dart_CodeObserver delegate_; | 
|  | }; | 
|  |  | 
|  | void CodeObservers::RegisterExternal(Dart_CodeObserver observer) { | 
|  | Register(new ExternalCodeObserverAdapter(observer)); | 
|  | } | 
|  |  | 
|  | void CodeObservers::Register(CodeObserver* observer) { | 
|  | observers_length_++; | 
|  | observers_ = reinterpret_cast<CodeObserver**>( | 
|  | realloc(observers_, sizeof(observer) * observers_length_)); | 
|  | observers_[observers_length_ - 1] = observer; | 
|  | } | 
|  |  | 
|  | void CodeObservers::NotifyAll(const char* name, | 
|  | uword base, | 
|  | uword prologue_offset, | 
|  | uword size, | 
|  | bool optimized, | 
|  | const CodeComments* comments) { | 
|  | ASSERT(!AreActive() || (strlen(name) != 0)); | 
|  | for (intptr_t i = 0; i < observers_length_; i++) { | 
|  | if (observers_[i]->IsActive()) { | 
|  | observers_[i]->Notify(name, base, prologue_offset, size, optimized, | 
|  | comments); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | bool CodeObservers::AreActive() { | 
|  | for (intptr_t i = 0; i < observers_length_; i++) { | 
|  | if (observers_[i]->IsActive()) return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void CodeObservers::Cleanup() { | 
|  | for (intptr_t i = 0; i < observers_length_; i++) { | 
|  | delete observers_[i]; | 
|  | } | 
|  | free(observers_); | 
|  | observers_length_ = 0; | 
|  | observers_ = nullptr; | 
|  | } | 
|  |  | 
|  | void CodeObservers::Init() { | 
|  | if (mutex_ == nullptr) { | 
|  | mutex_ = new Mutex(); | 
|  | } | 
|  | ASSERT(mutex_ != nullptr); | 
|  | OS::RegisterCodeObservers(); | 
|  | } | 
|  |  | 
|  | #endif  // !PRODUCT | 
|  |  | 
|  | }  // namespace dart |