Home | History | Annotate | Download | only in src
      1 // Copyright 2018 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/turbo-assembler.h"
      6 
      7 #include "src/builtins/builtins.h"
      8 #include "src/builtins/constants-table-builder.h"
      9 #include "src/heap/heap-inl.h"
     10 #include "src/lsan.h"
     11 #include "src/snapshot/serializer-common.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 TurboAssemblerBase::TurboAssemblerBase(Isolate* isolate,
     17                                        const AssemblerOptions& options,
     18                                        void* buffer, int buffer_size,
     19                                        CodeObjectRequired create_code_object)
     20     : Assembler(options, buffer, buffer_size), isolate_(isolate) {
     21   if (create_code_object == CodeObjectRequired::kYes) {
     22     code_object_ = Handle<HeapObject>::New(
     23         ReadOnlyRoots(isolate).self_reference_marker(), isolate);
     24   }
     25 }
     26 
     27 void TurboAssemblerBase::IndirectLoadConstant(Register destination,
     28                                               Handle<HeapObject> object) {
     29   CHECK(root_array_available_);
     30 
     31   // Before falling back to the (fairly slow) lookup from the constants table,
     32   // check if any of the fast paths can be applied.
     33 
     34   int builtin_index;
     35   Heap::RootListIndex root_index;
     36   if (isolate()->heap()->IsRootHandle(object, &root_index)) {
     37     // Roots are loaded relative to the root register.
     38     LoadRoot(destination, root_index);
     39   } else if (isolate()->builtins()->IsBuiltinHandle(object, &builtin_index)) {
     40     // Similar to roots, builtins may be loaded from the builtins table.
     41     LoadRootRelative(destination,
     42                      RootRegisterOffsetForBuiltinIndex(builtin_index));
     43   } else if (object.is_identical_to(code_object_) &&
     44              Builtins::IsBuiltinId(maybe_builtin_index_)) {
     45     // The self-reference loaded through Codevalue() may also be a builtin
     46     // and thus viable for a fast load.
     47     LoadRootRelative(destination,
     48                      RootRegisterOffsetForBuiltinIndex(maybe_builtin_index_));
     49   } else {
     50     CHECK(isolate()->ShouldLoadConstantsFromRootList());
     51     // Ensure the given object is in the builtins constants table and fetch its
     52     // index.
     53     BuiltinsConstantsTableBuilder* builder =
     54         isolate()->builtins_constants_table_builder();
     55     uint32_t index = builder->AddObject(object);
     56 
     57     // Slow load from the constants table.
     58     LoadFromConstantsTable(destination, index);
     59   }
     60 }
     61 
     62 void TurboAssemblerBase::IndirectLoadExternalReference(
     63     Register destination, ExternalReference reference) {
     64   CHECK(root_array_available_);
     65 
     66   if (IsAddressableThroughRootRegister(isolate(), reference)) {
     67     // Some external references can be efficiently loaded as an offset from
     68     // kRootRegister.
     69     intptr_t offset =
     70         RootRegisterOffsetForExternalReference(isolate(), reference);
     71     LoadRootRegisterOffset(destination, offset);
     72   } else {
     73     // Otherwise, do a memory load from the external reference table.
     74 
     75     // Encode as an index into the external reference table stored on the
     76     // isolate.
     77     ExternalReferenceEncoder encoder(isolate());
     78     ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
     79     CHECK(!v.is_from_api());
     80 
     81     LoadRootRelative(destination,
     82                      RootRegisterOffsetForExternalReferenceIndex(v.index()));
     83   }
     84 }
     85 
     86 // static
     87 int32_t TurboAssemblerBase::RootRegisterOffset(Heap::RootListIndex root_index) {
     88   return (root_index << kPointerSizeLog2) - kRootRegisterBias;
     89 }
     90 
     91 // static
     92 int32_t TurboAssemblerBase::RootRegisterOffsetForExternalReferenceIndex(
     93     int reference_index) {
     94   return Heap::roots_to_external_reference_table_offset() - kRootRegisterBias +
     95          ExternalReferenceTable::OffsetOfEntry(reference_index);
     96 }
     97 
     98 // static
     99 intptr_t TurboAssemblerBase::RootRegisterOffsetForExternalReference(
    100     Isolate* isolate, const ExternalReference& reference) {
    101   return static_cast<intptr_t>(reference.address()) - kRootRegisterBias -
    102          reinterpret_cast<intptr_t>(isolate->heap()->roots_array_start());
    103 }
    104 
    105 // static
    106 bool TurboAssemblerBase::IsAddressableThroughRootRegister(
    107     Isolate* isolate, const ExternalReference& reference) {
    108   Address start = reinterpret_cast<Address>(isolate);
    109   Address end = isolate->heap()->root_register_addressable_end();
    110   Address address = reference.address();
    111   return start <= address && address < end;
    112 }
    113 
    114 // static
    115 int32_t TurboAssemblerBase::RootRegisterOffsetForBuiltinIndex(
    116     int builtin_index) {
    117   return Heap::roots_to_builtins_offset() - kRootRegisterBias +
    118          builtin_index * kPointerSize;
    119 }
    120 
    121 void TurboAssemblerBase::RecordCommentForOffHeapTrampoline(int builtin_index) {
    122   if (!FLAG_code_comments) return;
    123   size_t len = strlen("-- Inlined Trampoline to  --") +
    124                strlen(Builtins::name(builtin_index)) + 1;
    125   Vector<char> buffer = Vector<char>::New(static_cast<int>(len));
    126   char* buffer_start = buffer.start();
    127   LSAN_IGNORE_OBJECT(buffer_start);
    128   SNPrintF(buffer, "-- Inlined Trampoline to %s --",
    129            Builtins::name(builtin_index));
    130   RecordComment(buffer_start);
    131 }
    132 
    133 }  // namespace internal
    134 }  // namespace v8
    135