11cb0ef41Sopenharmony_ci// Copyright 2020 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/codegen/external-reference-encoder.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/codegen/external-reference-table.h" 81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cinamespace v8 { 111cb0ef41Sopenharmony_cinamespace internal { 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) { 141cb0ef41Sopenharmony_ci#ifdef DEBUG 151cb0ef41Sopenharmony_ci api_references_ = isolate->api_external_references(); 161cb0ef41Sopenharmony_ci if (api_references_ != nullptr) { 171cb0ef41Sopenharmony_ci for (uint32_t i = 0; api_references_[i] != 0; ++i) count_.push_back(0); 181cb0ef41Sopenharmony_ci } 191cb0ef41Sopenharmony_ci#endif // DEBUG 201cb0ef41Sopenharmony_ci map_ = isolate->external_reference_map(); 211cb0ef41Sopenharmony_ci if (map_ != nullptr) return; 221cb0ef41Sopenharmony_ci map_ = new AddressToIndexHashMap(); 231cb0ef41Sopenharmony_ci isolate->set_external_reference_map(map_); 241cb0ef41Sopenharmony_ci // Add V8's external references. 251cb0ef41Sopenharmony_ci ExternalReferenceTable* table = isolate->external_reference_table(); 261cb0ef41Sopenharmony_ci for (uint32_t i = 0; i < ExternalReferenceTable::kSize; ++i) { 271cb0ef41Sopenharmony_ci Address addr = table->address(i); 281cb0ef41Sopenharmony_ci // Ignore duplicate references. 291cb0ef41Sopenharmony_ci // This can happen due to ICF. See http://crbug.com/726896. 301cb0ef41Sopenharmony_ci if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, false)); 311cb0ef41Sopenharmony_ci DCHECK(map_->Get(addr).IsJust()); 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci // Add external references provided by the embedder. 341cb0ef41Sopenharmony_ci const intptr_t* api_references = isolate->api_external_references(); 351cb0ef41Sopenharmony_ci if (api_references == nullptr) return; 361cb0ef41Sopenharmony_ci for (uint32_t i = 0; api_references[i] != 0; ++i) { 371cb0ef41Sopenharmony_ci Address addr = static_cast<Address>(api_references[i]); 381cb0ef41Sopenharmony_ci // Ignore duplicate references. 391cb0ef41Sopenharmony_ci // This can happen due to ICF. See http://crbug.com/726896. 401cb0ef41Sopenharmony_ci if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, true)); 411cb0ef41Sopenharmony_ci DCHECK(map_->Get(addr).IsJust()); 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci} 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci#ifdef DEBUG 461cb0ef41Sopenharmony_ciExternalReferenceEncoder::~ExternalReferenceEncoder() { 471cb0ef41Sopenharmony_ci if (!i::FLAG_external_reference_stats) return; 481cb0ef41Sopenharmony_ci if (api_references_ == nullptr) return; 491cb0ef41Sopenharmony_ci for (uint32_t i = 0; api_references_[i] != 0; ++i) { 501cb0ef41Sopenharmony_ci Address addr = static_cast<Address>(api_references_[i]); 511cb0ef41Sopenharmony_ci DCHECK(map_->Get(addr).IsJust()); 521cb0ef41Sopenharmony_ci v8::base::OS::Print( 531cb0ef41Sopenharmony_ci "index=%5d count=%5d %-60s\n", i, count_[i], 541cb0ef41Sopenharmony_ci ExternalReferenceTable::ResolveSymbol(reinterpret_cast<void*>(addr))); 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci} 571cb0ef41Sopenharmony_ci#endif // DEBUG 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ciMaybe<ExternalReferenceEncoder::Value> ExternalReferenceEncoder::TryEncode( 601cb0ef41Sopenharmony_ci Address address) { 611cb0ef41Sopenharmony_ci Maybe<uint32_t> maybe_index = map_->Get(address); 621cb0ef41Sopenharmony_ci if (maybe_index.IsNothing()) return Nothing<Value>(); 631cb0ef41Sopenharmony_ci Value result(maybe_index.FromJust()); 641cb0ef41Sopenharmony_ci#ifdef DEBUG 651cb0ef41Sopenharmony_ci if (result.is_from_api()) count_[result.index()]++; 661cb0ef41Sopenharmony_ci#endif // DEBUG 671cb0ef41Sopenharmony_ci return Just<Value>(result); 681cb0ef41Sopenharmony_ci} 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ciExternalReferenceEncoder::Value ExternalReferenceEncoder::Encode( 711cb0ef41Sopenharmony_ci Address address) { 721cb0ef41Sopenharmony_ci Maybe<uint32_t> maybe_index = map_->Get(address); 731cb0ef41Sopenharmony_ci if (maybe_index.IsNothing()) { 741cb0ef41Sopenharmony_ci void* addr = reinterpret_cast<void*>(address); 751cb0ef41Sopenharmony_ci v8::base::OS::PrintError("Unknown external reference %p.\n", addr); 761cb0ef41Sopenharmony_ci v8::base::OS::PrintError("%s\n", 771cb0ef41Sopenharmony_ci ExternalReferenceTable::ResolveSymbol(addr)); 781cb0ef41Sopenharmony_ci v8::base::OS::Abort(); 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci Value result(maybe_index.FromJust()); 811cb0ef41Sopenharmony_ci#ifdef DEBUG 821cb0ef41Sopenharmony_ci if (result.is_from_api()) count_[result.index()]++; 831cb0ef41Sopenharmony_ci#endif // DEBUG 841cb0ef41Sopenharmony_ci return result; 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciconst char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, 881cb0ef41Sopenharmony_ci Address address) const { 891cb0ef41Sopenharmony_ci Maybe<uint32_t> maybe_index = map_->Get(address); 901cb0ef41Sopenharmony_ci if (maybe_index.IsNothing()) return "<unknown>"; 911cb0ef41Sopenharmony_ci Value value(maybe_index.FromJust()); 921cb0ef41Sopenharmony_ci if (value.is_from_api()) return "<from api>"; 931cb0ef41Sopenharmony_ci return isolate->external_reference_table()->name(value.index()); 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci} // namespace internal 971cb0ef41Sopenharmony_ci} // namespace v8 98