| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
| 6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
| 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/js-operator.h" |
| 9 #include "src/compiler/linkage.h" | 11 #include "src/compiler/linkage.h" |
| 12 #include "src/compiler/machine-operator.h" |
| 10 #include "src/compiler/pipeline.h" | 13 #include "src/compiler/pipeline.h" |
| 11 #include "src/parser.h" | 14 #include "src/parser.h" |
| 12 #include "test/cctest/compiler/function-tester.h" | 15 #include "test/cctest/compiler/function-tester.h" |
| 13 | 16 |
| 14 #if V8_TURBOFAN_TARGET | 17 #if V8_TURBOFAN_TARGET |
| 15 | 18 |
| 16 using namespace v8::internal; | 19 using namespace v8::internal; |
| 17 using namespace v8::internal::compiler; | 20 using namespace v8::internal::compiler; |
| 18 | 21 |
| 19 | 22 |
| 20 static Handle<JSFunction> GetFunction(Isolate* isolate, const char* name) { | 23 TEST(RunMathFloorStub) { |
| 21 v8::ExtensionConfiguration no_extensions; | 24 HandleAndZoneScope scope; |
| 22 Handle<Context> ctx = isolate->bootstrapper()->CreateEnvironment( | 25 Isolate* isolate = scope.main_isolate(); |
| 23 MaybeHandle<JSGlobalProxy>(), v8::Handle<v8::ObjectTemplate>(), | 26 |
| 24 &no_extensions); | 27 // Create code and an accompanying descriptor. |
| 25 Handle<JSBuiltinsObject> builtins = handle(ctx->builtins()); | 28 MathFloorStub stub(isolate); |
| 26 MaybeHandle<Object> fun = Object::GetProperty(isolate, builtins, name); | 29 Handle<Code> code = stub.GenerateCode(); |
| 27 Handle<JSFunction> function = Handle<JSFunction>::cast(fun.ToHandleChecked()); | 30 Zone* zone = scope.main_zone(); |
| 28 // Just to make sure nobody calls this... | 31 |
| 29 function->set_code(isolate->builtins()->builtin(Builtins::kIllegal)); | 32 CompilationInfo info(&stub, isolate, zone); |
| 30 return function; | 33 CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info); |
| 34 |
| 35 // Create a function to call the code using the descriptor. |
| 36 Graph graph(zone); |
| 37 CommonOperatorBuilder common(zone); |
| 38 JSOperatorBuilder javascript(zone); |
| 39 MachineOperatorBuilder machine(zone); |
| 40 JSGraph js(isolate, &graph, &common, &javascript, &machine); |
| 41 |
| 42 // FunctionTester (ab)uses a 2-argument function |
| 43 Node* start = graph.NewNode(common.Start(2)); |
| 44 // Parameter 0 is the number to round |
| 45 Node* numberParam = graph.NewNode(common.Parameter(1), start); |
| 46 Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code); |
| 47 Node* theCode = graph.NewNode(common.HeapConstant(u)); |
| 48 Node* dummyContext = graph.NewNode(common.NumberConstant(0.0)); |
| 49 Node* call = graph.NewNode(common.Call(descriptor), theCode, |
| 50 js.UndefinedConstant(), js.UndefinedConstant(), |
| 51 numberParam, dummyContext, start, start); |
| 52 Node* ret = graph.NewNode(common.Return(), call, call, start); |
| 53 Node* end = graph.NewNode(common.End(), ret); |
| 54 graph.SetStart(start); |
| 55 graph.SetEnd(end); |
| 56 FunctionTester ft(&graph); |
| 57 |
| 58 Handle<Object> value = ft.Val(1.5); |
| 59 Handle<Object> result = ft.Call(value, value).ToHandleChecked(); |
| 60 CHECK_EQ(1, Smi::cast(*result)->value()); |
| 31 } | 61 } |
| 32 | 62 |
| 33 | 63 |
| 34 class StringLengthStubTF : public CodeStub { | 64 TEST(RunStringLengthTFStub) { |
| 35 public: | |
| 36 explicit StringLengthStubTF(Isolate* isolate) : CodeStub(isolate) {} | |
| 37 | |
| 38 StringLengthStubTF(uint32_t key, Isolate* isolate) : CodeStub(key, isolate) {} | |
| 39 | |
| 40 CallInterfaceDescriptor GetCallInterfaceDescriptor() override { | |
| 41 return LoadDescriptor(isolate()); | |
| 42 }; | |
| 43 | |
| 44 Handle<Code> GenerateCode() override { | |
| 45 Zone zone; | |
| 46 // Build a "hybrid" CompilationInfo for a JSFunction/CodeStub pair. | |
| 47 ParseInfo parse_info(&zone, GetFunction(isolate(), "STRING_LENGTH_STUB")); | |
| 48 CompilationInfo info(&parse_info); | |
| 49 info.SetStub(this); | |
| 50 // Run a "mini pipeline", extracted from compiler.cc. | |
| 51 CHECK(Parser::ParseStatic(info.parse_info())); | |
| 52 CHECK(Compiler::Analyze(info.parse_info())); | |
| 53 return Pipeline(&info).GenerateCode(); | |
| 54 } | |
| 55 | |
| 56 Major MajorKey() const override { return StringLength; }; | |
| 57 Code::Kind GetCodeKind() const override { return Code::HANDLER; } | |
| 58 InlineCacheState GetICState() const override { return MONOMORPHIC; } | |
| 59 ExtraICState GetExtraICState() const override { return Code::LOAD_IC; } | |
| 60 Code::StubType GetStubType() const override { return Code::FAST; } | |
| 61 | |
| 62 private: | |
| 63 DISALLOW_COPY_AND_ASSIGN(StringLengthStubTF); | |
| 64 }; | |
| 65 | |
| 66 | |
| 67 TEST(RunStringLengthStubTF) { | |
| 68 HandleAndZoneScope scope; | 65 HandleAndZoneScope scope; |
| 69 Isolate* isolate = scope.main_isolate(); | 66 Isolate* isolate = scope.main_isolate(); |
| 70 Zone* zone = scope.main_zone(); | 67 Zone* zone = scope.main_zone(); |
| 71 | 68 |
| 72 // Create code and an accompanying descriptor. | 69 // Create code and an accompanying descriptor. |
| 73 StringLengthStubTF stub(isolate); | 70 StringLengthTFStub stub(isolate); |
| 74 Handle<Code> code = stub.GenerateCode(); | 71 Handle<Code> code = stub.GenerateCode(); |
| 75 CompilationInfo info(&stub, isolate, zone); | 72 CompilationInfo info(&stub, isolate, zone); |
| 76 CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info); | 73 CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info); |
| 77 | 74 |
| 78 // Create a function to call the code using the descriptor. | 75 // Create a function to call the code using the descriptor. |
| 79 Graph graph(zone); | 76 Graph graph(zone); |
| 80 CommonOperatorBuilder common(zone); | 77 CommonOperatorBuilder common(zone); |
| 81 // FunctionTester (ab)uses a 2-argument function | 78 // FunctionTester (ab)uses a 2-argument function |
| 82 Node* start = graph.NewNode(common.Start(2)); | 79 Node* start = graph.NewNode(common.Start(2)); |
| 83 // Parameter 0 is the receiver | 80 // Parameter 0 is the receiver |
| (...skipping 13 matching lines...) Expand all Loading... |
| 97 // Actuall call through to the stub, verifying its result. | 94 // Actuall call through to the stub, verifying its result. |
| 98 const char* testString = "Und das Lamm schrie HURZ!"; | 95 const char* testString = "Und das Lamm schrie HURZ!"; |
| 99 Handle<JSReceiver> receiverArg = | 96 Handle<JSReceiver> receiverArg = |
| 100 Object::ToObject(isolate, ft.Val(testString)).ToHandleChecked(); | 97 Object::ToObject(isolate, ft.Val(testString)).ToHandleChecked(); |
| 101 Handle<String> nameArg = ft.Val("length"); | 98 Handle<String> nameArg = ft.Val("length"); |
| 102 Handle<Object> result = ft.Call(receiverArg, nameArg).ToHandleChecked(); | 99 Handle<Object> result = ft.Call(receiverArg, nameArg).ToHandleChecked(); |
| 103 CHECK_EQ(static_cast<int>(strlen(testString)), Smi::cast(*result)->value()); | 100 CHECK_EQ(static_cast<int>(strlen(testString)), Smi::cast(*result)->value()); |
| 104 } | 101 } |
| 105 | 102 |
| 106 #endif // V8_TURBOFAN_TARGET | 103 #endif // V8_TURBOFAN_TARGET |
| OLD | NEW |