Line data Source code
1 : // Copyright 2014 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/api-inl.h"
6 : #include "src/code-factory.h"
7 : #include "src/compiler.h"
8 : #include "src/compiler/common-operator.h"
9 : #include "src/compiler/graph.h"
10 : #include "src/compiler/linkage.h"
11 : #include "src/compiler/machine-operator.h"
12 : #include "src/compiler/node.h"
13 : #include "src/compiler/operator.h"
14 : #include "src/compiler/pipeline.h"
15 : #include "src/compiler/schedule.h"
16 : #include "src/objects-inl.h"
17 : #include "src/optimized-compilation-info.h"
18 : #include "src/parsing/parse-info.h"
19 : #include "src/zone/zone.h"
20 : #include "test/cctest/cctest.h"
21 :
22 : namespace v8 {
23 : namespace internal {
24 : namespace compiler {
25 :
26 56674 : static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
27 28337 : "dummy", 0, 0, 0, 0, 0, 0);
28 :
29 : // So we can get a real JS function.
30 10 : static Handle<JSFunction> Compile(const char* source) {
31 : Isolate* isolate = CcTest::i_isolate();
32 : Handle<String> source_code = isolate->factory()
33 : ->NewStringFromUtf8(CStrVector(source))
34 20 : .ToHandleChecked();
35 : Handle<SharedFunctionInfo> shared =
36 : Compiler::GetSharedFunctionInfoForScript(
37 : isolate, source_code, Compiler::ScriptDetails(),
38 : v8::ScriptOriginOptions(), nullptr, nullptr,
39 : v8::ScriptCompiler::kNoCompileOptions,
40 10 : ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE)
41 20 : .ToHandleChecked();
42 : return isolate->factory()->NewFunctionFromSharedFunctionInfo(
43 20 : shared, isolate->native_context());
44 : }
45 :
46 :
47 28342 : TEST(TestLinkageCreate) {
48 5 : HandleAndZoneScope handles;
49 5 : Handle<JSFunction> function = Compile("a + b");
50 15 : Handle<SharedFunctionInfo> shared(function->shared(), handles.main_isolate());
51 : OptimizedCompilationInfo info(handles.main_zone(), function->GetIsolate(),
52 10 : shared, function);
53 5 : auto call_descriptor = Linkage::ComputeIncoming(info.zone(), &info);
54 10 : CHECK(call_descriptor);
55 5 : }
56 :
57 :
58 28342 : TEST(TestLinkageJSFunctionIncoming) {
59 : const char* sources[] = {"(function() { })", "(function(a) { })",
60 5 : "(function(a,b) { })", "(function(a,b,c) { })"};
61 :
62 25 : for (int i = 0; i < 3; i++) {
63 15 : HandleAndZoneScope handles;
64 : Handle<JSFunction> function =
65 : Handle<JSFunction>::cast(v8::Utils::OpenHandle(
66 30 : *v8::Local<v8::Function>::Cast(CompileRun(sources[i]))));
67 : Handle<SharedFunctionInfo> shared(function->shared(),
68 45 : handles.main_isolate());
69 : OptimizedCompilationInfo info(handles.main_zone(), function->GetIsolate(),
70 30 : shared, function);
71 60 : auto call_descriptor = Linkage::ComputeIncoming(info.zone(), &info);
72 15 : CHECK(call_descriptor);
73 :
74 15 : CHECK_EQ(1 + i, static_cast<int>(call_descriptor->JSParameterCount()));
75 15 : CHECK_EQ(1, static_cast<int>(call_descriptor->ReturnCount()));
76 30 : CHECK_EQ(Operator::kNoProperties, call_descriptor->properties());
77 15 : CHECK_EQ(true, call_descriptor->IsJSFunctionCall());
78 15 : }
79 5 : }
80 :
81 :
82 28342 : TEST(TestLinkageJSCall) {
83 5 : HandleAndZoneScope handles;
84 5 : Handle<JSFunction> function = Compile("a + c");
85 15 : Handle<SharedFunctionInfo> shared(function->shared(), handles.main_isolate());
86 : OptimizedCompilationInfo info(handles.main_zone(), function->GetIsolate(),
87 10 : shared, function);
88 :
89 165 : for (int i = 0; i < 32; i++) {
90 480 : auto call_descriptor = Linkage::GetJSCallDescriptor(
91 160 : info.zone(), false, i, CallDescriptor::kNoFlags);
92 160 : CHECK(call_descriptor);
93 160 : CHECK_EQ(i, static_cast<int>(call_descriptor->JSParameterCount()));
94 160 : CHECK_EQ(1, static_cast<int>(call_descriptor->ReturnCount()));
95 320 : CHECK_EQ(Operator::kNoProperties, call_descriptor->properties());
96 160 : CHECK_EQ(true, call_descriptor->IsJSFunctionCall());
97 5 : }
98 5 : }
99 :
100 :
101 28342 : TEST(TestLinkageRuntimeCall) {
102 : // TODO(titzer): test linkage creation for outgoing runtime calls.
103 5 : }
104 :
105 :
106 28342 : TEST(TestLinkageStubCall) {
107 5 : Isolate* isolate = CcTest::InitIsolateOnce();
108 5 : Zone zone(isolate->allocator(), ZONE_NAME);
109 5 : Callable callable = Builtins::CallableFor(isolate, Builtins::kToNumber);
110 10 : OptimizedCompilationInfo info(ArrayVector("test"), &zone, Code::STUB);
111 15 : auto call_descriptor = Linkage::GetStubCallDescriptor(
112 : &zone, callable.descriptor(), 0, CallDescriptor::kNoFlags,
113 10 : Operator::kNoProperties);
114 5 : CHECK(call_descriptor);
115 5 : CHECK_EQ(0, static_cast<int>(call_descriptor->StackParameterCount()));
116 5 : CHECK_EQ(1, static_cast<int>(call_descriptor->ReturnCount()));
117 10 : CHECK_EQ(Operator::kNoProperties, call_descriptor->properties());
118 10 : CHECK_EQ(false, call_descriptor->IsJSFunctionCall());
119 : // TODO(titzer): test linkage creation for outgoing stub calls.
120 5 : }
121 :
122 : } // namespace compiler
123 : } // namespace internal
124 85011 : } // namespace v8
|