Line data Source code
1 : // Copyright 2017 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/debug/debug-type-profile.h"
6 :
7 : #include "src/feedback-vector.h"
8 : #include "src/isolate.h"
9 : #include "src/objects-inl.h"
10 : #include "src/objects.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 50 : std::unique_ptr<TypeProfile> TypeProfile::Collect(Isolate* isolate) {
16 50 : std::unique_ptr<TypeProfile> result(new TypeProfile());
17 :
18 : // Feedback vectors are already listed to prevent losing them to GC.
19 : DCHECK(isolate->factory()
20 : ->feedback_vectors_for_profiling_tools()
21 : ->IsArrayList());
22 : Handle<ArrayList> list = Handle<ArrayList>::cast(
23 : isolate->factory()->feedback_vectors_for_profiling_tools());
24 :
25 50 : Script::Iterator scripts(isolate);
26 :
27 825 : while (Script* script = scripts.Next()) {
28 775 : if (!script->IsUserJavaScript()) {
29 650 : continue;
30 : }
31 :
32 : Handle<Script> script_handle(script, isolate);
33 :
34 : TypeProfileScript type_profile_script(script_handle);
35 : std::vector<TypeProfileEntry>* entries = &type_profile_script.entries;
36 :
37 : // TODO(franzih): Sort the vectors by script first instead of iterating
38 : // the list multiple times.
39 2060 : for (int i = 0; i < list->Length(); i++) {
40 : FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
41 : SharedFunctionInfo* info = vector->shared_function_info();
42 : DCHECK(info->IsSubjectToDebugging());
43 :
44 : // Match vectors with script.
45 1810 : if (script != info->script()) {
46 1660 : continue;
47 : }
48 770 : if (info->feedback_metadata()->is_empty() ||
49 370 : !info->feedback_metadata()->HasTypeProfileSlot()) {
50 : continue;
51 : }
52 150 : FeedbackSlot slot = vector->GetTypeProfileSlot();
53 : CollectTypeProfileNexus nexus(vector, slot);
54 150 : Handle<String> name(info->DebugName(), isolate);
55 150 : std::vector<int> source_positions = nexus.GetSourcePositions();
56 485 : for (int position : source_positions) {
57 : DCHECK_GE(position, 0);
58 : entries->emplace_back(position, nexus.GetTypesForSourcePositions(
59 370 : static_cast<uint32_t>(position)));
60 : }
61 :
62 : // Releases type profile data collected so far.
63 150 : nexus.Clear();
64 : }
65 125 : if (!entries->empty()) {
66 40 : result->emplace_back(type_profile_script);
67 : }
68 : }
69 50 : return result;
70 : }
71 :
72 125 : void TypeProfile::SelectMode(Isolate* isolate, debug::TypeProfile::Mode mode) {
73 : HandleScope handle_scope(isolate);
74 :
75 125 : if (mode == debug::TypeProfile::Mode::kNone) {
76 60 : if (!isolate->factory()
77 : ->feedback_vectors_for_profiling_tools()
78 : ->IsUndefined(isolate)) {
79 : // Release type profile data collected so far.
80 :
81 : // Feedback vectors are already listed to prevent losing them to GC.
82 : DCHECK(isolate->factory()
83 : ->feedback_vectors_for_profiling_tools()
84 : ->IsArrayList());
85 : Handle<ArrayList> list = Handle<ArrayList>::cast(
86 : isolate->factory()->feedback_vectors_for_profiling_tools());
87 :
88 525 : for (int i = 0; i < list->Length(); i++) {
89 : FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
90 : SharedFunctionInfo* info = vector->shared_function_info();
91 : DCHECK(info->IsSubjectToDebugging());
92 475 : if (info->feedback_metadata()->HasTypeProfileSlot()) {
93 135 : FeedbackSlot slot = vector->GetTypeProfileSlot();
94 : CollectTypeProfileNexus nexus(vector, slot);
95 135 : nexus.Clear();
96 : }
97 : }
98 :
99 : // Delete the feedback vectors from the list if they're not used by code
100 : // coverage.
101 50 : if (isolate->is_best_effort_code_coverage()) {
102 : isolate->SetFeedbackVectorsForProfilingTools(
103 50 : isolate->heap()->undefined_value());
104 : }
105 : }
106 : } else {
107 : DCHECK_EQ(debug::TypeProfile::Mode::kCollect, mode);
108 65 : if (isolate->factory()->feedback_vectors_for_profiling_tools()->IsUndefined(
109 : isolate)) {
110 60 : isolate->InitializeVectorListFromHeap();
111 : }
112 : }
113 : isolate->set_type_profile_mode(mode);
114 125 : }
115 :
116 : } // namespace internal
117 : } // namespace v8
|