blob: 151e240f2505c89d6db87b4ed3829533df6c3471 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include "src/runtime/runtime.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006
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"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012#include "src/runtime/runtime-utils.h"
13
14namespace v8 {
15namespace 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);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
22#undef F
Emily Bernierd0a1eb72015-03-24 16:35:39 -040023
24#define P(name, number_of_args, result_size) \
25 ObjectPair Runtime_##name(int args_length, Object** args_object, \
26 Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027FOR_EACH_INTRINSIC_RETURN_PAIR(P)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028#undef P
29
Ben Murdoch097c5b22016-05-18 11:27:45 +010030#define T(name, number_of_args, result_size) \
31 ObjectTriple Runtime_##name(int args_length, Object** args_object, \
32 Isolate* isolate);
33FOR_EACH_INTRINSIC_RETURN_TRIPLE(T)
34#undef T
35
Emily Bernierd0a1eb72015-03-24 16:35:39 -040036
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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045#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 } \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050 ,
51
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052static const Runtime::Function kIntrinsicFunctions[] = {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 FOR_EACH_INTRINSIC(F)
54 FOR_EACH_INTRINSIC(I)
55};
Emily Bernierd0a1eb72015-03-24 16:35:39 -040056
Emily Bernierd0a1eb72015-03-24 16:35:39 -040057#undef I
58#undef F
59
60
61void 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),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails::Empty());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040071 // The dictionary does not need to grow.
72 CHECK(new_dict.is_identical_to(dict));
73 }
74}
75
76
77const 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
89const 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
99const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
100 return &(kIntrinsicFunctions[static_cast<int>(id)]);
101}
102
103
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104const 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400129std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
130 return os << Runtime::FunctionForId(id)->name;
131}
132
Ben Murdoch097c5b22016-05-18 11:27:45 +0100133
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400134} // namespace internal
135} // namespace v8