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