| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bin/builtin.h" | 5 #include "bin/builtin.h" |
| 6 #include "include/dart_api.h" | 6 #include "include/dart_api.h" |
| 7 #include "include/dart_mirrors_api.h" | 7 #include "include/dart_mirrors_api.h" |
| 8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
| 9 #include "include/dart_tools_api.h" | 9 #include "include/dart_tools_api.h" |
| 10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
| (...skipping 9242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9253 0, | 9253 0, |
| 9254 NULL); | 9254 NULL); |
| 9255 EXPECT_VALID(result); | 9255 EXPECT_VALID(result); |
| 9256 | 9256 |
| 9257 const char* buffer = NULL; | 9257 const char* buffer = NULL; |
| 9258 intptr_t buffer_length = 0; | 9258 intptr_t buffer_length = 0; |
| 9259 bool success = false; | 9259 bool success = false; |
| 9260 | 9260 |
| 9261 // Grab the global trace. | 9261 // Grab the global trace. |
| 9262 AppendData data; | 9262 AppendData data; |
| 9263 success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data); | 9263 { |
| 9264 EXPECT(success); | 9264 Thread* T = Thread::Current(); |
| 9265 StackZone zone(T); |
| 9266 success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data); |
| 9267 EXPECT(success); |
| 9268 // The call should do no zone allocation. |
| 9269 EXPECT(zone.SizeInBytes() == 0); |
| 9270 } |
| 9265 buffer = reinterpret_cast<char*>(data.buffer); | 9271 buffer = reinterpret_cast<char*>(data.buffer); |
| 9266 buffer_length = data.buffer_length; | 9272 buffer_length = data.buffer_length; |
| 9267 EXPECT(buffer_length > 0); | 9273 EXPECT(buffer_length > 0); |
| 9268 EXPECT(buffer != NULL); | 9274 EXPECT(buffer != NULL); |
| 9269 | 9275 |
| 9270 // Response starts with a '{' character and not a '['. | 9276 // Response starts with a '{' character and not a '['. |
| 9271 EXPECT(buffer[0] == '{'); | 9277 EXPECT(buffer[0] == '{'); |
| 9272 // Response ends with a '}' character and not a ']'. | 9278 // Response ends with a '}' character and not a ']'. |
| 9273 EXPECT(buffer[buffer_length - 1] == '\0'); | 9279 EXPECT(buffer[buffer_length - 1] == '\0'); |
| 9274 EXPECT(buffer[buffer_length - 2] == '}'); | 9280 EXPECT(buffer[buffer_length - 2] == '}'); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 9294 "TestVMDuration2"); | 9300 "TestVMDuration2"); |
| 9295 // Invoke bar, which will be compiled resulting in a compiler event in | 9301 // Invoke bar, which will be compiled resulting in a compiler event in |
| 9296 // the timeline. | 9302 // the timeline. |
| 9297 result = Dart_Invoke(lib, | 9303 result = Dart_Invoke(lib, |
| 9298 NewString("bar"), | 9304 NewString("bar"), |
| 9299 0, | 9305 0, |
| 9300 NULL); | 9306 NULL); |
| 9301 } | 9307 } |
| 9302 | 9308 |
| 9303 // Grab the global trace. | 9309 // Grab the global trace. |
| 9304 success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data); | 9310 { |
| 9305 EXPECT(success); | 9311 Thread* T = Thread::Current(); |
| 9312 StackZone zone(T); |
| 9313 success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data); |
| 9314 EXPECT(success); |
| 9315 EXPECT(zone.SizeInBytes() == 0); |
| 9316 } |
| 9306 buffer = reinterpret_cast<char*>(data.buffer); | 9317 buffer = reinterpret_cast<char*>(data.buffer); |
| 9307 buffer_length = data.buffer_length; | 9318 buffer_length = data.buffer_length; |
| 9308 EXPECT(buffer_length > 0); | 9319 EXPECT(buffer_length > 0); |
| 9309 EXPECT(buffer != NULL); | 9320 EXPECT(buffer != NULL); |
| 9310 // Response starts with a '{' character and not a '['. | 9321 // Response starts with a '{' character and not a '['. |
| 9311 EXPECT(buffer[0] == '{'); | 9322 EXPECT(buffer[0] == '{'); |
| 9312 // Response ends with a '}' character and not a ']'. | 9323 // Response ends with a '}' character and not a ']'. |
| 9313 EXPECT(buffer[buffer_length - 1] == '\0'); | 9324 EXPECT(buffer[buffer_length - 1] == '\0'); |
| 9314 EXPECT(buffer[buffer_length - 2] == '}'); | 9325 EXPECT(buffer[buffer_length - 2] == '}'); |
| 9315 | 9326 |
| 9316 // Heartbeat test for old events. | 9327 // Heartbeat test for old events. |
| 9317 EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer); | 9328 EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer); |
| 9318 EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer); | 9329 EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer); |
| 9319 EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer); | 9330 EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer); |
| 9320 EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer); | 9331 EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer); |
| 9321 | 9332 |
| 9322 // Heartbeat test for new events. | 9333 // Heartbeat test for new events. |
| 9323 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); | 9334 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); |
| 9324 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); | 9335 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); |
| 9325 | 9336 |
| 9326 // Free buffer allocated by AppendStreamConsumer | 9337 // Free buffer allocated by AppendStreamConsumer |
| 9327 free(data.buffer); | 9338 free(data.buffer); |
| 9328 } | 9339 } |
| 9329 | 9340 |
| 9341 |
| 9342 class GlobalTimelineThreadData { |
| 9343 public: |
| 9344 GlobalTimelineThreadData() |
| 9345 : monitor_(new Monitor()), |
| 9346 data_(new AppendData()), |
| 9347 running_(true), |
| 9348 join_id_(OSThread::kInvalidThreadJoinId) { |
| 9349 } |
| 9350 |
| 9351 ~GlobalTimelineThreadData() { |
| 9352 delete monitor_; |
| 9353 monitor_ = NULL; |
| 9354 free(data_->buffer); |
| 9355 data_->buffer = NULL; |
| 9356 data_->buffer_length = 0; |
| 9357 delete data_; |
| 9358 data_ = NULL; |
| 9359 } |
| 9360 |
| 9361 Monitor* monitor() const { return monitor_; } |
| 9362 bool running() const { return running_; } |
| 9363 AppendData* data() const { return data_; } |
| 9364 uint8_t* buffer() const { return data_->buffer; } |
| 9365 intptr_t buffer_length() const { return data_->buffer_length; } |
| 9366 ThreadJoinId join_id() const { return join_id_; } |
| 9367 |
| 9368 void set_running(bool running) { running_ = running; } |
| 9369 void set_join_id(ThreadJoinId join_id) { join_id_ = join_id; } |
| 9370 |
| 9371 private: |
| 9372 Monitor* monitor_; |
| 9373 AppendData* data_; |
| 9374 bool running_; |
| 9375 ThreadJoinId join_id_; |
| 9376 }; |
| 9377 |
| 9378 |
| 9379 static void GlobalTimelineThread(uword parameter) { |
| 9380 GlobalTimelineThreadData* data = |
| 9381 reinterpret_cast<GlobalTimelineThreadData*>(parameter); |
| 9382 Thread* T = Thread::Current(); |
| 9383 // When there is no current Thread, then Zone allocation will fail. |
| 9384 EXPECT(T == NULL); |
| 9385 { |
| 9386 MonitorLocker ml(data->monitor()); |
| 9387 bool success = |
| 9388 Dart_GlobalTimelineGetTrace(AppendStreamConsumer, data->data()); |
| 9389 EXPECT(success); |
| 9390 data->set_running(false); |
| 9391 data->set_join_id(OSThread::Current()->join_id()); |
| 9392 ml.Notify(); |
| 9393 } |
| 9394 } |
| 9395 |
| 9396 |
| 9397 // This test is the same as the one above except that the calls to |
| 9398 // Dart_GlobalTimelineGetTrace are made from a fresh thread. This ensures that |
| 9399 // we can call the function from a thread for which we have not set up a |
| 9400 // Thread object. |
| 9401 TEST_CASE(Timeline_Dart_GlobalTimelineGetTrace_Threaded) { |
| 9402 const char* kScriptChars = |
| 9403 "bar() => 'z';\n" |
| 9404 "foo() => 'a';\n" |
| 9405 "main() => foo();\n"; |
| 9406 |
| 9407 // Enable all streams. |
| 9408 Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL | |
| 9409 DART_TIMELINE_STREAM_VM); |
| 9410 Dart_Handle lib; |
| 9411 { |
| 9412 // Add something to the VM stream. |
| 9413 TimelineDurationScope tds(Timeline::GetVMStream(), |
| 9414 "TestVMDuration"); |
| 9415 lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 9416 } |
| 9417 |
| 9418 // Invoke main, which will be compiled resulting in a compiler event in |
| 9419 // the timeline. |
| 9420 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 9421 EXPECT_VALID(result); |
| 9422 |
| 9423 const char* buffer = NULL; |
| 9424 intptr_t buffer_length = 0; |
| 9425 |
| 9426 // Run Dart_GlobalTimelineGetTrace on a fresh thread. |
| 9427 GlobalTimelineThreadData data; |
| 9428 int err = OSThread::Start("Timeline test thread", |
| 9429 GlobalTimelineThread, reinterpret_cast<uword>(&data)); |
| 9430 EXPECT(err == 0); |
| 9431 { |
| 9432 MonitorLocker ml(data.monitor()); |
| 9433 while (data.running()) { |
| 9434 ml.Wait(); |
| 9435 } |
| 9436 buffer = reinterpret_cast<char*>(data.buffer()); |
| 9437 buffer_length = data.buffer_length(); |
| 9438 OSThread::Join(data.join_id()); |
| 9439 } |
| 9440 EXPECT(buffer_length > 0); |
| 9441 EXPECT(buffer != NULL); |
| 9442 |
| 9443 // Response starts with a '{' character and not a '['. |
| 9444 EXPECT(buffer[0] == '{'); |
| 9445 // Response ends with a '}' character and not a ']'. |
| 9446 EXPECT(buffer[buffer_length - 1] == '\0'); |
| 9447 EXPECT(buffer[buffer_length - 2] == '}'); |
| 9448 |
| 9449 // Heartbeat test. |
| 9450 EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer); |
| 9451 EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer); |
| 9452 EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer); |
| 9453 EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer); |
| 9454 EXPECT_NOTSUBSTRING("\"function\":\"::_bar\"", buffer); |
| 9455 |
| 9456 // Retrieving the global trace resulted in all open blocks being reclaimed. |
| 9457 // Add some new events and verify that both sets of events are present |
| 9458 // in the resulting trace. |
| 9459 { |
| 9460 // Add something to the VM stream. |
| 9461 TimelineDurationScope tds(Timeline::GetVMStream(), |
| 9462 "TestVMDuration2"); |
| 9463 // Invoke bar, which will be compiled resulting in a compiler event in |
| 9464 // the timeline. |
| 9465 result = Dart_Invoke(lib, NewString("bar"), 0, NULL); |
| 9466 } |
| 9467 |
| 9468 // Grab the global trace. |
| 9469 GlobalTimelineThreadData data2; |
| 9470 err = OSThread::Start("Timeline test thread", |
| 9471 GlobalTimelineThread, reinterpret_cast<uword>(&data2)); |
| 9472 EXPECT(err == 0); |
| 9473 { |
| 9474 MonitorLocker ml(data2.monitor()); |
| 9475 while (data2.running()) { |
| 9476 ml.Wait(); |
| 9477 } |
| 9478 buffer = reinterpret_cast<char*>(data2.buffer()); |
| 9479 buffer_length = data2.buffer_length(); |
| 9480 OSThread::Join(data2.join_id()); |
| 9481 } |
| 9482 |
| 9483 EXPECT(buffer_length > 0); |
| 9484 EXPECT(buffer != NULL); |
| 9485 // Response starts with a '{' character and not a '['. |
| 9486 EXPECT(buffer[0] == '{'); |
| 9487 // Response ends with a '}' character and not a ']'. |
| 9488 EXPECT(buffer[buffer_length - 1] == '\0'); |
| 9489 EXPECT(buffer[buffer_length - 2] == '}'); |
| 9490 |
| 9491 // Heartbeat test for old events. |
| 9492 EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer); |
| 9493 EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer); |
| 9494 EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer); |
| 9495 EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer); |
| 9496 |
| 9497 // Heartbeat test for new events. |
| 9498 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); |
| 9499 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); |
| 9500 } |
| 9501 |
| 9330 } // namespace dart | 9502 } // namespace dart |
| OLD | NEW |