// Copyright 2020 the V8 project 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 "src/codegen/external-reference-encoder.h" #include "src/codegen/external-reference-table.h" #include "src/execution/isolate.h" namespace v8 { namespace internal { ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) { #ifdef DEBUG api_references_ = isolate->api_external_references(); if (api_references_ != nullptr) { for (uint32_t i = 0; api_references_[i] != 0; ++i) count_.push_back(0); } #endif // DEBUG map_ = isolate->external_reference_map(); if (map_ != nullptr) return; map_ = new AddressToIndexHashMap(); isolate->set_external_reference_map(map_); // Add V8's external references. ExternalReferenceTable* table = isolate->external_reference_table(); for (uint32_t i = 0; i < ExternalReferenceTable::kSize; ++i) { Address addr = table->address(i); // Ignore duplicate references. // This can happen due to ICF. See http://crbug.com/726896. if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, false)); DCHECK(map_->Get(addr).IsJust()); } // Add external references provided by the embedder. const intptr_t* api_references = isolate->api_external_references(); if (api_references == nullptr) return; for (uint32_t i = 0; api_references[i] != 0; ++i) { Address addr = static_cast
(api_references[i]); // Ignore duplicate references. // This can happen due to ICF. See http://crbug.com/726896. if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, true)); DCHECK(map_->Get(addr).IsJust()); } } #ifdef DEBUG ExternalReferenceEncoder::~ExternalReferenceEncoder() { if (!i::FLAG_external_reference_stats) return; if (api_references_ == nullptr) return; for (uint32_t i = 0; api_references_[i] != 0; ++i) { Address addr = static_cast(api_references_[i]); DCHECK(map_->Get(addr).IsJust()); v8::base::OS::Print( "index=%5d count=%5d %-60s\n", i, count_[i], ExternalReferenceTable::ResolveSymbol(reinterpret_cast