| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 ~TestSetup() { | 112 ~TestSetup() { |
| 113 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_; | 113 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_; |
| 114 } | 114 } |
| 115 | 115 |
| 116 private: | 116 private: |
| 117 bool old_flag_prof_browser_mode_; | 117 bool old_flag_prof_browser_mode_; |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 } // namespace | 120 } // namespace |
| 121 | 121 |
| 122 | 122 i::AbstractCode* CreateCode(LocalContext* env) { |
| 123 i::Code* CreateCode(LocalContext* env) { | |
| 124 static int counter = 0; | 123 static int counter = 0; |
| 125 i::EmbeddedVector<char, 256> script; | 124 i::EmbeddedVector<char, 256> script; |
| 126 i::EmbeddedVector<char, 32> name; | 125 i::EmbeddedVector<char, 32> name; |
| 127 | 126 |
| 128 i::SNPrintF(name, "function_%d", ++counter); | 127 i::SNPrintF(name, "function_%d", ++counter); |
| 129 const char* name_start = name.start(); | 128 const char* name_start = name.start(); |
| 130 i::SNPrintF(script, | 129 i::SNPrintF(script, |
| 131 "function %s() {\n" | 130 "function %s() {\n" |
| 132 "var counter = 0;\n" | 131 "var counter = 0;\n" |
| 133 "for (var i = 0; i < %d; ++i) counter += i;\n" | 132 "for (var i = 0; i < %d; ++i) counter += i;\n" |
| 134 "return '%s_' + counter;\n" | 133 "return '%s_' + counter;\n" |
| 135 "}\n" | 134 "}\n" |
| 136 "%s();\n", name_start, counter, name_start, name_start); | 135 "%s();\n", name_start, counter, name_start, name_start); |
| 137 CompileRun(script.start()); | 136 CompileRun(script.start()); |
| 138 | 137 |
| 139 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast( | 138 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast( |
| 140 v8::Utils::OpenHandle(*GetFunction(env->local(), name_start))); | 139 v8::Utils::OpenHandle(*GetFunction(env->local(), name_start))); |
| 141 return fun->code(); | 140 return fun->abstract_code(); |
| 142 } | 141 } |
| 143 | 142 |
| 144 | |
| 145 TEST(CodeEvents) { | 143 TEST(CodeEvents) { |
| 146 CcTest::InitializeVM(); | 144 CcTest::InitializeVM(); |
| 147 LocalContext env; | 145 LocalContext env; |
| 148 i::Isolate* isolate = CcTest::i_isolate(); | 146 i::Isolate* isolate = CcTest::i_isolate(); |
| 149 i::Factory* factory = isolate->factory(); | 147 i::Factory* factory = isolate->factory(); |
| 150 TestSetup test_setup; | 148 TestSetup test_setup; |
| 151 | 149 |
| 152 i::HandleScope scope(isolate); | 150 i::HandleScope scope(isolate); |
| 153 | 151 |
| 154 i::Code* aaa_code = CreateCode(&env); | 152 i::AbstractCode* aaa_code = CreateCode(&env); |
| 155 i::Code* comment_code = CreateCode(&env); | 153 i::AbstractCode* comment_code = CreateCode(&env); |
| 156 i::Code* args5_code = CreateCode(&env); | 154 i::AbstractCode* args5_code = CreateCode(&env); |
| 157 i::Code* comment2_code = CreateCode(&env); | 155 i::AbstractCode* comment2_code = CreateCode(&env); |
| 158 i::Code* moved_code = CreateCode(&env); | 156 i::AbstractCode* moved_code = CreateCode(&env); |
| 159 i::Code* args3_code = CreateCode(&env); | 157 i::AbstractCode* args3_code = CreateCode(&env); |
| 160 i::Code* args4_code = CreateCode(&env); | 158 i::AbstractCode* args4_code = CreateCode(&env); |
| 161 | 159 |
| 162 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); | 160 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); |
| 163 profiles->StartProfiling("", false); | 161 profiles->StartProfiling("", false); |
| 164 ProfileGenerator generator(profiles); | 162 ProfileGenerator generator(profiles); |
| 165 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( | 163 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( |
| 166 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); | 164 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); |
| 167 processor->Start(); | 165 processor->Start(); |
| 168 CpuProfiler profiler(isolate, profiles, &generator, processor.get()); | 166 CpuProfiler profiler(isolate, profiles, &generator, processor.get()); |
| 169 | 167 |
| 170 // Enqueue code creation events. | 168 // Enqueue code creation events. |
| 171 const char* aaa_str = "aaa"; | 169 const char* aaa_str = "aaa"; |
| 172 i::Handle<i::String> aaa_name = factory->NewStringFromAsciiChecked(aaa_str); | 170 i::Handle<i::String> aaa_name = factory->NewStringFromAsciiChecked(aaa_str); |
| 173 profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, aaa_code, *aaa_name); | 171 profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, aaa_code, *aaa_name); |
| 174 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code, "comment"); | 172 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code, "comment"); |
| 175 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5); | 173 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5); |
| 176 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code, "comment2"); | 174 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code, "comment2"); |
| 177 profiler.CodeMoveEvent(comment2_code->address(), moved_code->address()); | 175 profiler.CodeMoveEvent(comment2_code, moved_code->address()); |
| 178 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3); | 176 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3); |
| 179 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4); | 177 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4); |
| 180 | 178 |
| 181 // Enqueue a tick event to enable code events processing. | 179 // Enqueue a tick event to enable code events processing. |
| 182 EnqueueTickSampleEvent(processor.get(), aaa_code->address()); | 180 EnqueueTickSampleEvent(processor.get(), aaa_code->address()); |
| 183 | 181 |
| 184 processor->StopSynchronously(); | 182 processor->StopSynchronously(); |
| 185 | 183 |
| 186 // Check the state of profile generator. | 184 // Check the state of profile generator. |
| 187 CodeEntry* aaa = generator.code_map()->FindEntry(aaa_code->address()); | 185 CodeEntry* aaa = generator.code_map()->FindEntry(aaa_code->address()); |
| 188 CHECK(aaa); | 186 CHECK(aaa); |
| 189 CHECK_EQ(0, strcmp(aaa_str, aaa->name())); | 187 CHECK_EQ(0, strcmp(aaa_str, aaa->name())); |
| 190 | 188 |
| 191 CodeEntry* comment = generator.code_map()->FindEntry(comment_code->address()); | 189 CodeEntry* comment = generator.code_map()->FindEntry(comment_code->address()); |
| 192 CHECK(comment); | 190 CHECK(comment); |
| 193 CHECK_EQ(0, strcmp("comment", comment->name())); | 191 CHECK_EQ(0, strcmp("comment", comment->name())); |
| 194 | 192 |
| 195 CodeEntry* args5 = generator.code_map()->FindEntry(args5_code->address()); | 193 CodeEntry* args5 = generator.code_map()->FindEntry(args5_code->address()); |
| 196 CHECK(args5); | 194 CHECK(args5); |
| 197 CHECK_EQ(0, strcmp("5", args5->name())); | 195 CHECK_EQ(0, strcmp("5", args5->name())); |
| 198 | 196 |
| 199 CHECK(!generator.code_map()->FindEntry(comment2_code->address())); | 197 CHECK(!generator.code_map()->FindEntry(comment2_code->address())); |
| 200 | 198 |
| 201 CodeEntry* comment2 = generator.code_map()->FindEntry(moved_code->address()); | 199 CodeEntry* comment2 = generator.code_map()->FindEntry(moved_code->address()); |
| 202 CHECK(comment2); | 200 CHECK(comment2); |
| 203 CHECK_EQ(0, strcmp("comment2", comment2->name())); | 201 CHECK_EQ(0, strcmp("comment2", comment2->name())); |
| 204 } | 202 } |
| 205 | 203 |
| 206 | |
| 207 template<typename T> | 204 template<typename T> |
| 208 static int CompareProfileNodes(const T* p1, const T* p2) { | 205 static int CompareProfileNodes(const T* p1, const T* p2) { |
| 209 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); | 206 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); |
| 210 } | 207 } |
| 211 | 208 |
| 212 | |
| 213 TEST(TickEvents) { | 209 TEST(TickEvents) { |
| 214 TestSetup test_setup; | 210 TestSetup test_setup; |
| 215 LocalContext env; | 211 LocalContext env; |
| 216 i::Isolate* isolate = CcTest::i_isolate(); | 212 i::Isolate* isolate = CcTest::i_isolate(); |
| 217 i::HandleScope scope(isolate); | 213 i::HandleScope scope(isolate); |
| 218 | 214 |
| 219 i::Code* frame1_code = CreateCode(&env); | 215 i::AbstractCode* frame1_code = CreateCode(&env); |
| 220 i::Code* frame2_code = CreateCode(&env); | 216 i::AbstractCode* frame2_code = CreateCode(&env); |
| 221 i::Code* frame3_code = CreateCode(&env); | 217 i::AbstractCode* frame3_code = CreateCode(&env); |
| 222 | 218 |
| 223 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); | 219 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); |
| 224 profiles->StartProfiling("", false); | 220 profiles->StartProfiling("", false); |
| 225 ProfileGenerator generator(profiles); | 221 ProfileGenerator generator(profiles); |
| 226 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( | 222 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( |
| 227 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); | 223 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); |
| 228 processor->Start(); | 224 processor->Start(); |
| 229 CpuProfiler profiler(isolate, profiles, &generator, processor.get()); | 225 CpuProfiler profiler(isolate, profiles, &generator, processor.get()); |
| 230 | 226 |
| 231 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb"); | 227 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb"); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 258 CHECK_EQ(0, strcmp("5", top_down_bbb_children->last()->entry()->name())); | 254 CHECK_EQ(0, strcmp("5", top_down_bbb_children->last()->entry()->name())); |
| 259 const i::List<ProfileNode*>* top_down_stub_children = | 255 const i::List<ProfileNode*>* top_down_stub_children = |
| 260 top_down_bbb_children->last()->children(); | 256 top_down_bbb_children->last()->children(); |
| 261 CHECK_EQ(1, top_down_stub_children->length()); | 257 CHECK_EQ(1, top_down_stub_children->length()); |
| 262 CHECK_EQ(0, strcmp("ddd", top_down_stub_children->last()->entry()->name())); | 258 CHECK_EQ(0, strcmp("ddd", top_down_stub_children->last()->entry()->name())); |
| 263 const i::List<ProfileNode*>* top_down_ddd_children = | 259 const i::List<ProfileNode*>* top_down_ddd_children = |
| 264 top_down_stub_children->last()->children(); | 260 top_down_stub_children->last()->children(); |
| 265 CHECK_EQ(0, top_down_ddd_children->length()); | 261 CHECK_EQ(0, top_down_ddd_children->length()); |
| 266 } | 262 } |
| 267 | 263 |
| 268 | |
| 269 // http://crbug/51594 | 264 // http://crbug/51594 |
| 270 // This test must not crash. | 265 // This test must not crash. |
| 271 TEST(CrashIfStoppingLastNonExistentProfile) { | 266 TEST(CrashIfStoppingLastNonExistentProfile) { |
| 272 CcTest::InitializeVM(); | 267 CcTest::InitializeVM(); |
| 273 TestSetup test_setup; | 268 TestSetup test_setup; |
| 274 CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); | 269 CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); |
| 275 profiler->StartProfiling("1"); | 270 profiler->StartProfiling("1"); |
| 276 profiler->StopProfiling("2"); | 271 profiler->StopProfiling("2"); |
| 277 profiler->StartProfiling("1"); | 272 profiler->StartProfiling("1"); |
| 278 profiler->StopProfiling(""); | 273 profiler->StopProfiling(""); |
| 279 } | 274 } |
| 280 | 275 |
| 281 | |
| 282 // http://code.google.com/p/v8/issues/detail?id=1398 | 276 // http://code.google.com/p/v8/issues/detail?id=1398 |
| 283 // Long stacks (exceeding max frames limit) must not be erased. | 277 // Long stacks (exceeding max frames limit) must not be erased. |
| 284 TEST(Issue1398) { | 278 TEST(Issue1398) { |
| 285 TestSetup test_setup; | 279 TestSetup test_setup; |
| 286 LocalContext env; | 280 LocalContext env; |
| 287 i::Isolate* isolate = CcTest::i_isolate(); | 281 i::Isolate* isolate = CcTest::i_isolate(); |
| 288 i::HandleScope scope(isolate); | 282 i::HandleScope scope(isolate); |
| 289 | 283 |
| 290 i::Code* code = CreateCode(&env); | 284 i::AbstractCode* code = CreateCode(&env); |
| 291 | 285 |
| 292 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); | 286 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); |
| 293 profiles->StartProfiling("", false); | 287 profiles->StartProfiling("", false); |
| 294 ProfileGenerator generator(profiles); | 288 ProfileGenerator generator(profiles); |
| 295 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( | 289 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( |
| 296 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); | 290 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); |
| 297 processor->Start(); | 291 processor->Start(); |
| 298 CpuProfiler profiler(isolate, profiles, &generator, processor.get()); | 292 CpuProfiler profiler(isolate, profiles, &generator, processor.get()); |
| 299 | 293 |
| 300 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb"); | 294 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb"); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 315 unsigned actual_depth = 0; | 309 unsigned actual_depth = 0; |
| 316 const ProfileNode* node = profile->top_down()->root(); | 310 const ProfileNode* node = profile->top_down()->root(); |
| 317 while (node->children()->length() > 0) { | 311 while (node->children()->length() > 0) { |
| 318 node = node->children()->last(); | 312 node = node->children()->last(); |
| 319 ++actual_depth; | 313 ++actual_depth; |
| 320 } | 314 } |
| 321 | 315 |
| 322 CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC. | 316 CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC. |
| 323 } | 317 } |
| 324 | 318 |
| 325 | |
| 326 TEST(DeleteAllCpuProfiles) { | 319 TEST(DeleteAllCpuProfiles) { |
| 327 CcTest::InitializeVM(); | 320 CcTest::InitializeVM(); |
| 328 TestSetup test_setup; | 321 TestSetup test_setup; |
| 329 CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); | 322 CpuProfiler* profiler = CcTest::i_isolate()->cpu_profiler(); |
| 330 CHECK_EQ(0, profiler->GetProfilesCount()); | 323 CHECK_EQ(0, profiler->GetProfilesCount()); |
| 331 profiler->DeleteAllProfiles(); | 324 profiler->DeleteAllProfiles(); |
| 332 CHECK_EQ(0, profiler->GetProfilesCount()); | 325 CHECK_EQ(0, profiler->GetProfilesCount()); |
| 333 | 326 |
| 334 profiler->StartProfiling("1"); | 327 profiler->StartProfiling("1"); |
| 335 profiler->StopProfiling("1"); | 328 profiler->StopProfiling("1"); |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 " }\n" | 1006 " }\n" |
| 1014 "}\n" | 1007 "}\n" |
| 1015 "%s();\n", | 1008 "%s();\n", |
| 1016 func_name, func_name); | 1009 func_name, func_name); |
| 1017 | 1010 |
| 1018 CompileRun(script.start()); | 1011 CompileRun(script.start()); |
| 1019 | 1012 |
| 1020 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( | 1013 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( |
| 1021 v8::Utils::OpenHandle(*GetFunction(env.local(), func_name))); | 1014 v8::Utils::OpenHandle(*GetFunction(env.local(), func_name))); |
| 1022 CHECK(func->shared()); | 1015 CHECK(func->shared()); |
| 1023 CHECK(func->shared()->code()); | 1016 CHECK(func->shared()->abstract_code()); |
| 1024 i::Code* code = NULL; | 1017 i::AbstractCode* code = NULL; |
| 1025 if (func->code()->is_optimized_code()) { | 1018 if (func->abstract_code()->kind() == i::AbstractCode::OPTIMIZED_FUNCTION) { |
| 1026 code = func->code(); | 1019 code = func->abstract_code(); |
| 1027 } else { | 1020 } else { |
| 1028 CHECK(func->shared()->code() == func->code() || !i::FLAG_crankshaft); | 1021 CHECK(func->shared()->abstract_code() == func->abstract_code() || |
| 1029 code = func->shared()->code(); | 1022 !i::FLAG_crankshaft); |
| 1023 code = func->shared()->abstract_code(); |
| 1030 } | 1024 } |
| 1031 CHECK(code); | 1025 CHECK(code); |
| 1032 i::Address code_address = code->instruction_start(); | 1026 i::Address code_address = code->instruction_start(); |
| 1033 CHECK(code_address); | 1027 CHECK(code_address); |
| 1034 | 1028 |
| 1035 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); | 1029 CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); |
| 1036 profiles->StartProfiling("", false); | 1030 profiles->StartProfiling("", false); |
| 1037 ProfileGenerator generator(profiles); | 1031 ProfileGenerator generator(profiles); |
| 1038 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( | 1032 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( |
| 1039 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); | 1033 &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1968 iprofile->Print(); | 1962 iprofile->Print(); |
| 1969 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); | 1963 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); |
| 1970 | 1964 |
| 1971 const char* branch[] = {"", "test"}; | 1965 const char* branch[] = {"", "test"}; |
| 1972 const ProfileNode* itest_node = | 1966 const ProfileNode* itest_node = |
| 1973 GetSimpleBranch(env, profile, branch, arraysize(branch)); | 1967 GetSimpleBranch(env, profile, branch, arraysize(branch)); |
| 1974 CHECK_EQ(0U, itest_node->deopt_infos().size()); | 1968 CHECK_EQ(0U, itest_node->deopt_infos().size()); |
| 1975 | 1969 |
| 1976 iprofiler->DeleteProfile(iprofile); | 1970 iprofiler->DeleteProfile(iprofile); |
| 1977 } | 1971 } |
| OLD | NEW |