Home | History | Annotate | Download | only in runtime
      1 // Copyright 2012 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/runtime/runtime.h"
      6 
      7 #include "src/assembler.h"
      8 #include "src/contexts.h"
      9 #include "src/handles-inl.h"
     10 #include "src/heap/heap.h"
     11 #include "src/isolate.h"
     12 #include "src/runtime/runtime-utils.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 // Header of runtime functions.
     18 #define F(name, number_of_args, result_size)                    \
     19   Object* Runtime_##name(int args_length, Object** args_object, \
     20                          Isolate* isolate);
     21 FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
     22 #undef F
     23 
     24 #define P(name, number_of_args, result_size)                       \
     25   ObjectPair Runtime_##name(int args_length, Object** args_object, \
     26                             Isolate* isolate);
     27 FOR_EACH_INTRINSIC_RETURN_PAIR(P)
     28 #undef P
     29 
     30 #define T(name, number_of_args, result_size)                         \
     31   ObjectTriple Runtime_##name(int args_length, Object** args_object, \
     32                               Isolate* isolate);
     33 FOR_EACH_INTRINSIC_RETURN_TRIPLE(T)
     34 #undef T
     35 
     36 
     37 #define F(name, number_of_args, result_size)                                  \
     38   {                                                                           \
     39     Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
     40         number_of_args, result_size                                           \
     41   }                                                                           \
     42   ,
     43 
     44 
     45 #define I(name, number_of_args, result_size)                       \
     46   {                                                                \
     47     Runtime::kInline##name, Runtime::INLINE, "_" #name,            \
     48         FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \
     49   }                                                                \
     50   ,
     51 
     52 static const Runtime::Function kIntrinsicFunctions[] = {
     53   FOR_EACH_INTRINSIC(F)
     54   FOR_EACH_INTRINSIC(I)
     55 };
     56 
     57 #undef I
     58 #undef F
     59 
     60 
     61 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
     62                                                Handle<NameDictionary> dict) {
     63   DCHECK(dict->NumberOfElements() == 0);
     64   HandleScope scope(isolate);
     65   for (int i = 0; i < kNumFunctions; ++i) {
     66     const char* name = kIntrinsicFunctions[i].name;
     67     if (name == NULL) continue;
     68     Handle<NameDictionary> new_dict = NameDictionary::Add(
     69         dict, isolate->factory()->InternalizeUtf8String(name),
     70         Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails::Empty());
     71     // The dictionary does not need to grow.
     72     CHECK(new_dict.is_identical_to(dict));
     73   }
     74 }
     75 
     76 
     77 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
     78   Heap* heap = name->GetHeap();
     79   int entry = heap->intrinsic_function_names()->FindEntry(name);
     80   if (entry != kNotFound) {
     81     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
     82     int function_index = Smi::cast(smi_index)->value();
     83     return &(kIntrinsicFunctions[function_index]);
     84   }
     85   return NULL;
     86 }
     87 
     88 
     89 const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
     90   for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
     91     if (entry == kIntrinsicFunctions[i].entry) {
     92       return &(kIntrinsicFunctions[i]);
     93     }
     94   }
     95   return NULL;
     96 }
     97 
     98 
     99 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
    100   return &(kIntrinsicFunctions[static_cast<int>(id)]);
    101 }
    102 
    103 
    104 const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
    105   if (isolate->external_reference_redirector()) {
    106     // When running with the simulator we need to provide a table which has
    107     // redirected runtime entry addresses.
    108     if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
    109       size_t function_count = arraysize(kIntrinsicFunctions);
    110       Function* redirected_functions = new Function[function_count];
    111       memcpy(redirected_functions, kIntrinsicFunctions,
    112              sizeof(kIntrinsicFunctions));
    113       for (size_t i = 0; i < function_count; i++) {
    114         ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i),
    115                                            isolate);
    116         redirected_functions[i].entry = redirected_entry.address();
    117       }
    118       isolate->runtime_state()->set_redirected_intrinsic_functions(
    119           redirected_functions);
    120     }
    121 
    122     return isolate->runtime_state()->redirected_intrinsic_functions();
    123   } else {
    124     return kIntrinsicFunctions;
    125   }
    126 }
    127 
    128 
    129 std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
    130   return os << Runtime::FunctionForId(id)->name;
    131 }
    132 
    133 
    134 }  // namespace internal
    135 }  // namespace v8
    136