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 <iostream> | 5 #include <iostream> |
6 | 6 |
7 #include "src/compiler/bytecode-graph-builder.h" | 7 #include "src/compiler/bytecode-graph-builder.h" |
8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
9 #include "src/compiler/graph-visualizer.h" | 9 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/instruction.h" | 10 #include "src/compiler/instruction.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 static const LanguageMode kLanguageModes[] = {LanguageMode::SLOPPY, | 28 static const LanguageMode kLanguageModes[] = {LanguageMode::SLOPPY, |
29 LanguageMode::STRICT}; | 29 LanguageMode::STRICT}; |
30 | 30 |
31 Handle<TypeFeedbackVector> NewTypeFeedbackVector(Isolate* isolate, | 31 Handle<TypeFeedbackVector> NewTypeFeedbackVector(Isolate* isolate, |
32 FeedbackVectorSpec* spec) { | 32 FeedbackVectorSpec* spec) { |
33 Handle<TypeFeedbackMetadata> vector_metadata = | 33 Handle<TypeFeedbackMetadata> vector_metadata = |
34 TypeFeedbackMetadata::New(isolate, spec); | 34 TypeFeedbackMetadata::New(isolate, spec); |
35 return TypeFeedbackVector::New(isolate, vector_metadata); | 35 return TypeFeedbackVector::New(isolate, vector_metadata); |
36 } | 36 } |
37 | 37 |
| 38 |
38 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { | 39 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { |
39 public: | 40 public: |
40 BytecodeGraphBuilderTest() {} | 41 BytecodeGraphBuilderTest() {} |
41 | 42 |
42 Graph* GetCompletedGraph(Handle<BytecodeArray> bytecode_array, | 43 Graph* GetCompletedGraph(Handle<BytecodeArray> bytecode_array, |
43 MaybeHandle<TypeFeedbackVector> feedback_vector = | 44 MaybeHandle<TypeFeedbackVector> feedback_vector = |
44 MaybeHandle<TypeFeedbackVector>(), | 45 MaybeHandle<TypeFeedbackVector>(), |
45 LanguageMode language_mode = LanguageMode::SLOPPY); | 46 LanguageMode language_mode = LanguageMode::SLOPPY); |
46 | 47 |
47 Matcher<Node*> IsUndefinedConstant(); | 48 Matcher<Node*> IsUndefinedConstant(); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 341 |
341 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); | 342 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
342 Matcher<Node*> load_named_matcher = IsJSLoadNamed( | 343 Matcher<Node*> load_named_matcher = IsJSLoadNamed( |
343 name, IsParameter(1), feedback_vector_matcher, start, start); | 344 name, IsParameter(1), feedback_vector_matcher, start, start); |
344 | 345 |
345 EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _)); | 346 EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _)); |
346 } | 347 } |
347 } | 348 } |
348 } | 349 } |
349 | 350 |
| 351 |
| 352 TEST_F(BytecodeGraphBuilderTest, CallProperty0) { |
| 353 FeedbackVectorSpec feedback_spec(zone()); |
| 354 FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot(); |
| 355 FeedbackVectorSlot load_slot = feedback_spec.AddLoadICSlot(); |
| 356 Handle<TypeFeedbackVector> vector = |
| 357 NewTypeFeedbackVector(isolate(), &feedback_spec); |
| 358 |
| 359 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
| 360 array_builder.set_locals_count(1); |
| 361 array_builder.set_context_count(0); |
| 362 array_builder.set_parameter_count(2); |
| 363 |
| 364 Handle<Name> func_name = GetName(isolate(), "func"); |
| 365 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name); |
| 366 |
| 367 interpreter::Register reg0 = interpreter::Register(0); |
| 368 array_builder.LoadNamedProperty( |
| 369 array_builder.Parameter(1), func_name_index, |
| 370 vector->GetIndex(load_slot), LanguageMode::SLOPPY) |
| 371 .StoreAccumulatorInRegister(reg0) |
| 372 .Call(reg0, array_builder.Parameter(1), 0, vector->GetIndex(call_slot)) |
| 373 .Return(); |
| 374 |
| 375 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector); |
| 376 Node* ret = graph->end()->InputAt(0); |
| 377 Node* start = graph->start(); |
| 378 |
| 379 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
| 380 Matcher<Node*> load_named_matcher = IsJSLoadNamed( |
| 381 func_name, IsParameter(1), feedback_vector_matcher, start, start); |
| 382 std::vector<Matcher<Node*>> call_inputs; |
| 383 call_inputs.push_back(load_named_matcher); |
| 384 call_inputs.push_back(IsParameter(1)); |
| 385 Matcher<Node*> call_matcher = |
| 386 IsJSCallFunction(call_inputs, load_named_matcher, IsIfSuccess(_)); |
| 387 |
| 388 EXPECT_THAT(ret, IsReturn(call_matcher, _, _)); |
| 389 } |
| 390 |
| 391 |
| 392 TEST_F(BytecodeGraphBuilderTest, CallProperty2) { |
| 393 FeedbackVectorSpec feedback_spec(zone()); |
| 394 FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot(); |
| 395 FeedbackVectorSlot load_slot = feedback_spec.AddLoadICSlot(); |
| 396 Handle<TypeFeedbackVector> vector = |
| 397 NewTypeFeedbackVector(isolate(), &feedback_spec); |
| 398 |
| 399 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
| 400 array_builder.set_locals_count(4); |
| 401 array_builder.set_context_count(0); |
| 402 array_builder.set_parameter_count(4); |
| 403 |
| 404 Handle<Name> func_name = GetName(isolate(), "func"); |
| 405 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name); |
| 406 |
| 407 interpreter::Register reg0 = interpreter::Register(0); |
| 408 interpreter::Register reg1 = interpreter::Register(1); |
| 409 interpreter::Register reg2 = interpreter::Register(2); |
| 410 interpreter::Register reg3 = interpreter::Register(3); |
| 411 array_builder.LoadNamedProperty( |
| 412 array_builder.Parameter(1), func_name_index, |
| 413 vector->GetIndex(load_slot), LanguageMode::SLOPPY) |
| 414 .StoreAccumulatorInRegister(reg0) |
| 415 .LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
| 416 .StoreAccumulatorInRegister(reg1) |
| 417 .LoadAccumulatorWithRegister(array_builder.Parameter(2)) |
| 418 .StoreAccumulatorInRegister(reg2) |
| 419 .LoadAccumulatorWithRegister(array_builder.Parameter(3)) |
| 420 .StoreAccumulatorInRegister(reg3) |
| 421 .Call(reg0, reg1, 2, vector->GetIndex(call_slot)) |
| 422 .Return(); |
| 423 |
| 424 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector); |
| 425 Node* ret = graph->end()->InputAt(0); |
| 426 Node* start = graph->start(); |
| 427 |
| 428 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
| 429 Matcher<Node*> load_named_matcher = IsJSLoadNamed( |
| 430 func_name, IsParameter(1), feedback_vector_matcher, start, start); |
| 431 std::vector<Matcher<Node*>> call_inputs; |
| 432 call_inputs.push_back(load_named_matcher); |
| 433 call_inputs.push_back(IsParameter(1)); |
| 434 call_inputs.push_back(IsParameter(2)); |
| 435 call_inputs.push_back(IsParameter(3)); |
| 436 Matcher<Node*> call_matcher = |
| 437 IsJSCallFunction(call_inputs, load_named_matcher, IsIfSuccess(_)); |
| 438 |
| 439 EXPECT_THAT(ret, IsReturn(call_matcher, _, _)); |
| 440 } |
| 441 |
| 442 |
350 } // namespace compiler | 443 } // namespace compiler |
351 } // namespace internal | 444 } // namespace internal |
352 } // namespace v8 | 445 } // namespace v8 |
OLD | NEW |