runtime.cc 5.67 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/runtime/runtime.h"
6

7
#include "src/assembler.h"
8
#include "src/base/hashmap.h"
9
#include "src/contexts.h"
10 11 12
#include "src/handles-inl.h"
#include "src/heap/heap.h"
#include "src/isolate.h"
13
#include "src/runtime/runtime-utils.h"
14

15 16
namespace v8 {
namespace internal {
17

18 19 20 21
// Header of runtime functions.
#define F(name, number_of_args, result_size)                    \
  Object* Runtime_##name(int args_length, Object** args_object, \
                         Isolate* isolate);
22 23
FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
#undef F
24 25 26 27

#define P(name, number_of_args, result_size)                       \
  ObjectPair Runtime_##name(int args_length, Object** args_object, \
                            Isolate* isolate);
28
FOR_EACH_INTRINSIC_RETURN_PAIR(P)
29
#undef P
30

31 32 33 34 35 36
#define T(name, number_of_args, result_size)                         \
  ObjectTriple Runtime_##name(int args_length, Object** args_object, \
                              Isolate* isolate);
FOR_EACH_INTRINSIC_RETURN_TRIPLE(T)
#undef T

37

38 39 40 41 42 43
#define F(name, number_of_args, result_size)                                  \
  {                                                                           \
    Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
        number_of_args, result_size                                           \
  }                                                                           \
  ,
44 45


46 47 48 49 50
#define I(name, number_of_args, result_size)                       \
  {                                                                \
    Runtime::kInline##name, Runtime::INLINE, "_" #name,            \
        FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \
  }                                                                \
51
  ,
52

53
static const Runtime::Function kIntrinsicFunctions[] = {
54 55 56
  FOR_EACH_INTRINSIC(F)
  FOR_EACH_INTRINSIC(I)
};
57

58 59 60
#undef I
#undef F

61
namespace {
62

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
V8_DECLARE_ONCE(initialize_function_name_map_once);
static const base::HashMap* kRuntimeFunctionNameMap;

struct IntrinsicFunctionIdentifier {
  IntrinsicFunctionIdentifier(const unsigned char* data, const int length)
      : data_(data), length_(length) {}

  static bool Match(void* key1, void* key2) {
    const IntrinsicFunctionIdentifier* lhs =
        static_cast<IntrinsicFunctionIdentifier*>(key1);
    const IntrinsicFunctionIdentifier* rhs =
        static_cast<IntrinsicFunctionIdentifier*>(key2);
    if (lhs->length_ != rhs->length_) return false;
    return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs->data_),
                                reinterpret_cast<const uint8_t*>(rhs->data_),
                                rhs->length_) == 0;
  }

  uint32_t Hash() {
    return StringHasher::HashSequentialString<uint8_t>(
        data_, length_, v8::internal::kZeroHashSeed);
84
  }
85

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
  const unsigned char* data_;
  const int length_;
};

void InitializeIntrinsicFunctionNames() {
  base::HashMap* function_name_map =
      new base::HashMap(IntrinsicFunctionIdentifier::Match);
  for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
    const Runtime::Function* function = &kIntrinsicFunctions[i];
    IntrinsicFunctionIdentifier* identifier = new IntrinsicFunctionIdentifier(
        reinterpret_cast<const unsigned char*>(function->name),
        static_cast<int>(strlen(function->name)));
    base::HashMap::Entry* entry =
        function_name_map->InsertNew(identifier, identifier->Hash());
    entry->value = const_cast<Runtime::Function*>(function);
  }
  kRuntimeFunctionNameMap = function_name_map;
}
104

105 106 107 108 109 110 111 112 113 114 115
}  // namespace

const Runtime::Function* Runtime::FunctionForName(const unsigned char* name,
                                                  int length) {
  base::CallOnce(&initialize_function_name_map_once,
                 &InitializeIntrinsicFunctionNames);
  IntrinsicFunctionIdentifier identifier(name, length);
  base::HashMap::Entry* entry =
      kRuntimeFunctionNameMap->Lookup(&identifier, identifier.Hash());
  if (entry) {
    return reinterpret_cast<Function*>(entry->value);
116 117 118 119 120
  }
  return NULL;
}


121
const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
122
  for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
123 124 125 126 127 128 129 130
    if (entry == kIntrinsicFunctions[i].entry) {
      return &(kIntrinsicFunctions[i]);
    }
  }
  return NULL;
}


131
const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
132 133
  return &(kIntrinsicFunctions[static_cast<int>(id)]);
}
134 135


136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
  if (isolate->external_reference_redirector()) {
    // When running with the simulator we need to provide a table which has
    // redirected runtime entry addresses.
    if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
      size_t function_count = arraysize(kIntrinsicFunctions);
      Function* redirected_functions = new Function[function_count];
      memcpy(redirected_functions, kIntrinsicFunctions,
             sizeof(kIntrinsicFunctions));
      for (size_t i = 0; i < function_count; i++) {
        ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i),
                                           isolate);
        redirected_functions[i].entry = redirected_entry.address();
      }
      isolate->runtime_state()->set_redirected_intrinsic_functions(
          redirected_functions);
    }

    return isolate->runtime_state()->redirected_intrinsic_functions();
  } else {
    return kIntrinsicFunctions;
  }
}


161 162
std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
  return os << Runtime::FunctionForId(id)->name;
163
}
164

165

166 167
}  // namespace internal
}  // namespace v8