Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: base/trace_event/trace_event_argument.cc

Issue 2975033002: [tracing] Optimize TracedValue::AppendAsTraceFormat(). (Closed)
Patch Set: Remove include Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/trace_event/trace_event_argument_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 The Chromium 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 "base/trace_event/trace_event_argument.h" 5 #include "base/trace_event/trace_event_argument.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <stack>
9 #include <utility> 10 #include <utility>
10 11
11 #include "base/bits.h" 12 #include "base/bits.h"
12 #include "base/json/json_writer.h" 13 #include "base/json/string_escape.h"
13 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/trace_event/common/trace_event_common.h"
16 #include "base/trace_event/trace_event_impl.h"
14 #include "base/trace_event/trace_event_memory_overhead.h" 17 #include "base/trace_event/trace_event_memory_overhead.h"
15 #include "base/values.h" 18 #include "base/values.h"
16 19
17 namespace base { 20 namespace base {
18 namespace trace_event { 21 namespace trace_event {
19 22
20 namespace { 23 namespace {
21 const char kTypeStartDict = '{'; 24 const char kTypeStartDict = '{';
22 const char kTypeEndDict = '}'; 25 const char kTypeEndDict = '}';
23 const char kTypeStartArray = '['; 26 const char kTypeStartArray = '[';
24 const char kTypeEndArray = ']'; 27 const char kTypeEndArray = ']';
25 const char kTypeBool = 'b'; 28 const char kTypeBool = 'b';
26 const char kTypeInt = 'i'; 29 const char kTypeInt = 'i';
27 const char kTypeDouble = 'd'; 30 const char kTypeDouble = 'd';
28 const char kTypeString = 's'; 31 const char kTypeString = 's';
29 const char kTypeCStr = '*'; 32 const char kTypeCStr = '*'; // only used for key names
30 33
31 #ifndef NDEBUG 34 #ifndef NDEBUG
32 const bool kStackTypeDict = false; 35 const bool kStackTypeDict = false;
33 const bool kStackTypeArray = true; 36 const bool kStackTypeArray = true;
34 #define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back()) 37 #define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back())
35 #define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size()) 38 #define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size())
36 #define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x) 39 #define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x)
37 #define DEBUG_POP_CONTAINER() nesting_stack_.pop_back() 40 #define DEBUG_POP_CONTAINER() nesting_stack_.pop_back()
38 #else 41 #else
39 #define DCHECK_CURRENT_CONTAINER_IS(x) do {} while (0) 42 #define DCHECK_CURRENT_CONTAINER_IS(x) do {} while (0)
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 } 450 }
448 } 451 }
449 DCHECK(stack.empty()); 452 DCHECK(stack.empty());
450 return std::move(root); 453 return std::move(root);
451 } 454 }
452 455
453 void TracedValue::AppendAsTraceFormat(std::string* out) const { 456 void TracedValue::AppendAsTraceFormat(std::string* out) const {
454 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); 457 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
455 DCHECK_CONTAINER_STACK_DEPTH_EQ(1u); 458 DCHECK_CONTAINER_STACK_DEPTH_EQ(1u);
456 459
457 // TODO(primiano): this could be smarter, skip the ToBaseValue encoding and 460 struct State {
Primiano Tucci (use gerrit) 2017/07/12 15:26:23 isn't this a gcc extension?
DmitrySkiba 2017/07/12 23:48:04 Inner structs? I believe it's valid C++11.
458 // produce the JSON on its own. This will require refactoring JSONWriter 461 enum Type { kTypeDict, kTypeArray };
459 // to decouple the base::Value traversal from the JSON writing bits 462 Type type;
460 std::string tmp; 463 bool needs_comma;
461 JSONWriter::Write(*ToBaseValue(), &tmp); 464 };
462 *out += tmp; 465
466 auto maybe_append_key_name = [](State current_state, PickleIterator* it,
467 std::string* out) {
468 if (current_state.type == State::kTypeDict) {
469 EscapeJSONString(ReadKeyName(*it), true, out);
470 out->append(":");
471 }
472 };
473
474 std::stack<State> state_stack;
475
476 out->append("{");
Primiano Tucci (use gerrit) 2017/07/12 15:26:23 I think all ths might be even faster if you build
DmitrySkiba 2017/07/12 23:48:04 I don't think there will be a difference - strings
477 state_stack.push({State::kTypeDict});
478
479 PickleIterator it(pickle_);
480 for (const char* type; it.ReadBytes(&type, 1);) {
481 switch (*type) {
482 case kTypeEndDict:
483 out->append("}");
484 state_stack.pop();
485 continue;
486
487 case kTypeEndArray:
488 out->append("]");
489 state_stack.pop();
490 continue;
491 }
492
493 State& current_state = state_stack.top();
494 if (current_state.needs_comma) {
495 out->append(",");
496 }
497
498 switch (*type) {
499 case kTypeStartDict:
500 maybe_append_key_name(current_state, &it, out);
501 out->append("{");
502 state_stack.push({State::kTypeDict});
503 break;
504
505 case kTypeStartArray:
506 maybe_append_key_name(current_state, &it, out);
507 out->append("[");
508 state_stack.push({State::kTypeArray});
509 break;
510
511 case kTypeBool: {
512 TraceEvent::TraceValue json_value;
513 CHECK(it.ReadBool(&json_value.as_bool));
514 maybe_append_key_name(current_state, &it, out);
515 TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_BOOL, json_value, out);
516 } break;
517
518 case kTypeInt: {
519 int value;
520 CHECK(it.ReadInt(&value));
521 maybe_append_key_name(current_state, &it, out);
522 TraceEvent::TraceValue json_value;
523 json_value.as_int = value;
524 TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_INT, json_value, out);
525 } break;
526
527 case kTypeDouble: {
528 TraceEvent::TraceValue json_value;
529 CHECK(it.ReadDouble(&json_value.as_double));
530 maybe_append_key_name(current_state, &it, out);
531 TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_DOUBLE, json_value, out);
532 } break;
533
534 case kTypeString: {
535 std::string value;
536 CHECK(it.ReadString(&value));
537 maybe_append_key_name(current_state, &it, out);
538 TraceEvent::TraceValue json_value;
539 json_value.as_string = value.c_str();
540 TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_STRING, json_value, out);
541 } break;
542
543 default:
544 NOTREACHED();
545 }
546
547 current_state.needs_comma = true;
548 }
549
550 out->append("}");
551 state_stack.pop();
552
553 DCHECK(state_stack.empty());
463 } 554 }
464 555
465 void TracedValue::EstimateTraceMemoryOverhead( 556 void TracedValue::EstimateTraceMemoryOverhead(
466 TraceEventMemoryOverhead* overhead) { 557 TraceEventMemoryOverhead* overhead) {
467 overhead->Add(TraceEventMemoryOverhead::kTracedValue, 558 overhead->Add(TraceEventMemoryOverhead::kTracedValue,
468 /* allocated size */ 559 /* allocated size */
469 pickle_.GetTotalAllocatedSize(), 560 pickle_.GetTotalAllocatedSize(),
470 /* resident size */ 561 /* resident size */
471 pickle_.size()); 562 pickle_.size());
472 } 563 }
473 564
474 } // namespace trace_event 565 } // namespace trace_event
475 } // namespace base 566 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/trace_event/trace_event_argument_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698