Revert "[vm] Enable timeline on Fuchsia even in product mode."

This reverts commit 3f7b371f2c0029f5b010d55961bda47c081ef9d6.

Reason for revert: Some modes failing to find new constant?

Original change's description:
> [vm] Enable timeline on Fuchsia even in product mode.
> 
> On Fuchsia, the timeline is accessed without involving the service isolate or vm-service.
> 
> Change-Id: I0d2351dcadcfc47835732235e1b8fafa8212f883
> Reviewed-on: https://dart-review.googlesource.com/c/89880
> Reviewed-by: Zach Anderson <zra@google.com>
> Commit-Queue: Ryan Macnak <rmacnak@google.com>

TBR=rmacnak@google.com,alexmarkov@google.com,zra@google.com,asiva@google.com

Change-Id: Ic03a78d14821e0361d54587f1f7510bc9ebfef1c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/89942
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 8255b23..3e68d99 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -16,24 +16,26 @@
 // Native implementations for the dart:developer library.
 
 DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0, 0) {
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
+  if (!FLAG_support_timeline) {
+    return Bool::False().raw();
+  }
   if (Timeline::GetDartStream()->enabled()) {
     return Bool::True().raw();
   }
-#endif
+#endif  // !PRODUCT
   return Bool::False().raw();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_getNextAsyncId, 0, 0) {
-#if !defined(SUPPORT_TIMELINE)
-  return Integer::New(0);
-#else
+  if (!FLAG_support_timeline) {
+    return Integer::New(0);
+  }
   TimelineEventRecorder* recorder = Timeline::recorder();
   if (recorder == NULL) {
     return Integer::New(0);
   }
   return Integer::New(recorder->GetNextAsyncId());
-#endif
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0, 0) {
@@ -45,7 +47,10 @@
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 6) {
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
+  if (!FLAG_support_timeline) {
+    return Object::null();
+  }
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments->NativeArgAt(2));
@@ -67,12 +72,15 @@
   DartTimelineEventHelpers::ReportTaskEvent(
       thread, event, start.AsInt64Value(), id.AsInt64Value(), phase.ToCString(),
       category.ToCString(), name.ToMallocCString(), args.ToMallocCString());
-#endif  // SUPPORT_TIMELINE
+#endif
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 0, 5) {
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
+  if (!FLAG_support_timeline) {
+    return Object::null();
+  }
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
@@ -93,12 +101,15 @@
   DartTimelineEventHelpers::ReportCompleteEvent(
       thread, event, start.AsInt64Value(), start_cpu.AsInt64Value(),
       category.ToCString(), name.ToMallocCString(), args.ToMallocCString());
-#endif  // SUPPORT_TIMELINE
+#endif  // !defined(PRODUCT)
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportFlowEvent, 0, 7) {
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
+  if (!FLAG_support_timeline) {
+    return Object::null();
+  }
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
@@ -122,12 +133,15 @@
       thread, event, start.AsInt64Value(), start_cpu.AsInt64Value(),
       category.ToCString(), name.ToMallocCString(), type.AsInt64Value(),
       flow_id.AsInt64Value(), args.ToMallocCString());
-#endif  // SUPPORT_TIMELINE
+#endif  // !defined(PRODUCT)
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 0, 4) {
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
+  if (!FLAG_support_timeline) {
+    return Object::null();
+  }
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
@@ -147,7 +161,7 @@
   DartTimelineEventHelpers::ReportInstantEvent(
       thread, event, start.AsInt64Value(), category.ToCString(),
       name.ToMallocCString(), args.ToMallocCString());
-#endif  // SUPPORT_TIMELINE
+#endif
   return Object::null();
 }
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 09fa482..572175d 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -172,7 +172,8 @@
 // b) after the user classes are loaded (dart_api).
 bool ClassFinalizer::ProcessPendingClasses() {
   Thread* thread = Thread::Current();
-  TIMELINE_DURATION(thread, Isolate, "ProcessPendingClasses");
+  NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
+                                           "ProcessPendingClasses"));
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   HANDLESCOPE(thread);
@@ -1126,7 +1127,10 @@
     THR_Print("Finalize %s\n", cls.ToCString());
   }
 
-  TIMELINE_DURATION(thread, Compiler, "ClassFinalizer::FinalizeClass");
+#if !defined(PRODUCT)
+  TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
+                            "ClassFinalizer::FinalizeClass");
+#endif  // !defined(PRODUCT)
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // If loading from a kernel, make sure that the class is fully loaded.
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index c25b1f9..db68c89 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -597,7 +597,8 @@
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    TIMELINE_DURATION(Thread::Current(), Isolate, "PostLoadFunction");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(
+        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadFunction"));
 
     if (kind == Snapshot::kFullAOT) {
       Function& func = Function::Handle(zone);
@@ -1010,7 +1011,8 @@
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    TIMELINE_DURATION(Thread::Current(), Isolate, "PostLoadField");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(
+        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadField"));
 
     Field& field = Field::Handle(zone);
     if (!Isolate::Current()->use_field_guards()) {
@@ -3283,7 +3285,8 @@
   void ReadFill(Deserializer* d) {}
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    TIMELINE_DURATION(Thread::Current(), Isolate, "PostLoadMint");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(
+        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadMint"));
 
     const Class& mint_cls =
         Class::Handle(zone, Isolate::Current()->object_store()->mint_class());
@@ -5104,7 +5107,8 @@
   }
 
   {
-    TIMELINE_DURATION(thread(), Isolate, "ReadAlloc");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(
+        thread(), Timeline::GetIsolateStream(), "ReadAlloc"));
     for (intptr_t i = 0; i < num_clusters_; i++) {
       clusters_[i] = ReadCluster();
       clusters_[i]->ReadAlloc(this);
@@ -5119,7 +5123,8 @@
   ASSERT((next_ref_index_ - 1) == num_objects_);
 
   {
-    TIMELINE_DURATION(thread(), Isolate, "ReadFill");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(
+        thread(), Timeline::GetIsolateStream(), "ReadFill"));
     for (intptr_t i = 0; i < num_clusters_; i++) {
       clusters_[i]->ReadFill(this);
 #if defined(DEBUG)
@@ -5417,7 +5422,8 @@
   // generated from a VM that has loaded this snapshots, much like app-jit
   // snapshots.
   if ((vm_snapshot_data_buffer != NULL) && (kind != Snapshot::kFullAOT)) {
-    TIMELINE_DURATION(thread(), Isolate, "PrepareNewVMIsolate");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(
+        thread(), Timeline::GetIsolateStream(), "PrepareNewVMIsolate"));
 
     SeedVMIsolateVisitor visitor(thread()->zone(),
                                  Snapshot::IncludesCode(kind));
@@ -5458,7 +5464,8 @@
 }
 
 intptr_t FullSnapshotWriter::WriteVMSnapshot() {
-  TIMELINE_DURATION(thread(), Isolate, "WriteVMSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds(
+      thread(), Timeline::GetIsolateStream(), "WriteVMSnapshot"));
 
   ASSERT(vm_snapshot_data_buffer_ != NULL);
   Serializer serializer(thread(), kind_, vm_snapshot_data_buffer_, alloc_,
@@ -5491,7 +5498,8 @@
 }
 
 void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
-  TIMELINE_DURATION(thread(), Isolate, "WriteIsolateSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds(
+      thread(), Timeline::GetIsolateStream(), "WriteIsolateSnapshot"));
 
   Serializer serializer(thread(), kind_, isolate_snapshot_data_buffer_, alloc_,
                         kInitialSize, isolate_image_writer_, /*vm=*/false,
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 5fb0fb2..1fc69d6 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2286,8 +2286,10 @@
 
       {
         ic_data_array = new (zone) ZoneGrowableArray<const ICData*>();
-
-        TIMELINE_DURATION(thread(), Compiler, "BuildFlowGraph");
+#ifndef PRODUCT
+        TimelineDurationScope tds(thread(), compiler_timeline,
+                                  "BuildFlowGraph");
+#endif  // !PRODUCT
         flow_graph =
             pipeline->BuildFlowGraph(zone, parsed_function(), ic_data_array,
                                      Compiler::kNoOSRDeoptId, optimized());
@@ -2315,7 +2317,10 @@
       NOT_IN_PRODUCT(pass_state.compiler_timeline = compiler_timeline);
 
       if (optimized()) {
-        TIMELINE_DURATION(thread(), Compiler, "OptimizationPasses");
+#ifndef PRODUCT
+        TimelineDurationScope tds(thread(), compiler_timeline,
+                                  "OptimizationPasses");
+#endif  // !PRODUCT
 
         pass_state.inline_id_to_function.Add(&function);
         // We do not add the token position now because we don't know the
@@ -2359,12 +2364,17 @@
           pass_state.inline_id_to_token_pos, pass_state.caller_inline_id,
           ic_data_array, function_stats);
       {
-        TIMELINE_DURATION(thread(), Compiler, "CompileGraph");
+#ifndef PRODUCT
+        TimelineDurationScope tds(thread(), compiler_timeline, "CompileGraph");
+#endif  // !PRODUCT
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation(flow_graph);
       }
       {
-        TIMELINE_DURATION(thread(), Compiler, "FinalizeCompilation");
+#ifndef PRODUCT
+        TimelineDurationScope tds(thread(), compiler_timeline,
+                                  "FinalizeCompilation");
+#endif  // !PRODUCT
         ASSERT(thread()->IsMutatorThread());
         FinalizeCompilation(&assembler, &graph_compiler, flow_graph,
                             function_stats);
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index cb1c7af..cb7360e 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -40,7 +40,12 @@
 }
 
 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
-  TIMELINE_DURATION(flow_graph->thread(), Compiler, "FlowGraphTypePropagator");
+#ifndef PRODUCT
+  Thread* thread = flow_graph->thread();
+  TimelineStream* compiler_timeline = Timeline::GetCompilerStream();
+  TimelineDurationScope tds2(thread, compiler_timeline,
+                             "FlowGraphTypePropagator");
+#endif  // !PRODUCT
   FlowGraphTypePropagator propagator(flow_graph);
   propagator.Propagate();
 }
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index d0f3d32..e72f1a3 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -173,7 +173,8 @@
 
     PrintGraph(state, kTraceBefore, round);
     {
-      TIMELINE_DURATION(thread, Compiler, name());
+      NOT_IN_PRODUCT(
+          TimelineDurationScope tds2(thread, state->compiler_timeline, name()));
       repeat = DoBody(state);
       DEBUG_ASSERT(state->flow_graph->VerifyUseLists());
       thread->CheckForSafepoint();
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 9f705c5..077b1b1 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -44,7 +44,7 @@
 }
 
 void BytecodeMetadataHelper::ReadMetadata(const Function& function) {
-#if defined(SUPPORT_TIMELINE)
+#if !defined(PRODUCT)
   TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
                             "BytecodeMetadataHelper::ReadMetadata");
   // This increases bytecode reading time by ~7%, so only keep it around for
@@ -310,8 +310,10 @@
 
 void BytecodeMetadataHelper::ReadConstantPool(const Function& function,
                                               const ObjectPool& pool) {
-  TIMELINE_DURATION(Thread::Current(), Compiler,
-                    "BytecodeMetadataHelper::ReadConstantPool");
+#if !defined(PRODUCT)
+  TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
+                            "BytecodeMetadataHelper::ReadConstantPool");
+#endif  // !defined(PRODUCT)
 
   // These enums and the code below reading the constant pool from kernel must
   // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart.
@@ -636,8 +638,10 @@
 }
 
 RawBytecode* BytecodeMetadataHelper::ReadBytecode(const ObjectPool& pool) {
-  TIMELINE_DURATION(Thread::Current(), Compiler,
-                    "BytecodeMetadataHelper::ReadBytecode");
+#if !defined(PRODUCT)
+  TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
+                            "BytecodeMetadataHelper::ReadBytecode");
+#endif  // !defined(PRODUCT)
   intptr_t size = helper_->ReadUInt();
   intptr_t offset = Utils::RoundUp(helper_->reader_.offset(), sizeof(KBCInstr));
   const uint8_t* data = helper_->reader_.BufferAt(offset);
@@ -655,8 +659,10 @@
 
 void BytecodeMetadataHelper::ReadExceptionsTable(const Bytecode& bytecode,
                                                  bool has_exceptions_table) {
-  TIMELINE_DURATION(Thread::Current(), Compiler,
-                    "BytecodeMetadataHelper::ReadExceptionsTable");
+#if !defined(PRODUCT)
+  TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
+                            "BytecodeMetadataHelper::ReadExceptionsTable");
+#endif  // !defined(PRODUCT)
 
   const intptr_t try_block_count =
       has_exceptions_table ? helper_->reader_.ReadListLength() : 0;
diff --git a/runtime/vm/compiler/intrinsifier_arm.cc b/runtime/vm/compiler/intrinsifier_arm.cc
index 8b51488..9e516f0 100644
--- a/runtime/vm/compiler/intrinsifier_arm.cc
+++ b/runtime/vm/compiler/intrinsifier_arm.cc
@@ -2227,10 +2227,10 @@
 
 void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
                                                 Label* normal_ir_body) {
-#if !defined(SUPPORT_TIMELINE)
-  __ LoadObject(R0, Bool::False());
-  __ Ret();
-#else
+  if (!FLAG_support_timeline) {
+    __ LoadObject(R0, Bool::False());
+    __ Ret();
+  }
   // Load TimelineStream*.
   __ ldr(R0, Address(THR, Thread::dart_stream_offset()));
   // Load uintptr_t from TimelineStream*.
@@ -2239,7 +2239,6 @@
   __ LoadObject(R0, Bool::True(), NE);
   __ LoadObject(R0, Bool::False(), EQ);
   __ Ret();
-#endif
 }
 
 void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
diff --git a/runtime/vm/compiler/intrinsifier_arm64.cc b/runtime/vm/compiler/intrinsifier_arm64.cc
index 16f8f0b..2abf1ed 100644
--- a/runtime/vm/compiler/intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/intrinsifier_arm64.cc
@@ -2288,10 +2288,10 @@
 
 void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
                                                 Label* normal_ir_body) {
-#if !defined(SUPPORT_TIMELINE)
-  __ LoadObject(R0, Bool::False());
-  __ ret();
-#else
+  if (!FLAG_support_timeline) {
+    __ LoadObject(R0, Bool::False());
+    __ ret();
+  }
   // Load TimelineStream*.
   __ ldr(R0, Address(THR, Thread::dart_stream_offset()));
   // Load uintptr_t from TimelineStream*.
@@ -2301,7 +2301,6 @@
   __ LoadObject(TMP, Bool::True());
   __ csel(R0, TMP, R0, NE);
   __ ret();
-#endif
 }
 
 void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
diff --git a/runtime/vm/compiler/intrinsifier_ia32.cc b/runtime/vm/compiler/intrinsifier_ia32.cc
index ff8de4f..cfb50f6 100644
--- a/runtime/vm/compiler/intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/intrinsifier_ia32.cc
@@ -2202,10 +2202,10 @@
 
 void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
                                                 Label* normal_ir_body) {
-#if !defined(SUPPORT_TIMELINE)
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-#else
+  if (!FLAG_support_timeline) {
+    __ LoadObject(EAX, Bool::False());
+    __ ret();
+  }
   Label true_label;
   // Load TimelineStream*.
   __ movl(EAX, Address(THR, Thread::dart_stream_offset()));
@@ -2220,7 +2220,6 @@
   __ Bind(&true_label);
   __ LoadObject(EAX, Bool::True());
   __ ret();
-#endif
 }
 
 void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
diff --git a/runtime/vm/compiler/intrinsifier_x64.cc b/runtime/vm/compiler/intrinsifier_x64.cc
index ac56407..a51b665 100644
--- a/runtime/vm/compiler/intrinsifier_x64.cc
+++ b/runtime/vm/compiler/intrinsifier_x64.cc
@@ -2229,10 +2229,11 @@
 
 void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
                                                 Label* normal_ir_body) {
-#if !defined(SUPPORT_TIMELINE)
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-#else
+  if (!FLAG_support_timeline) {
+    __ LoadObject(RAX, Bool::False());
+    __ ret();
+    return;
+  }
   Label true_label;
   // Load TimelineStream*.
   __ movq(RAX, Address(THR, Thread::dart_stream_offset()));
@@ -2247,7 +2248,6 @@
   __ Bind(&true_label);
   __ LoadObject(RAX, Bool::True());
   __ ret();
-#endif
 }
 
 void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 22acf86..c63af58 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -619,7 +619,8 @@
           }
         }
 
-        TIMELINE_DURATION(thread(), Compiler, "BuildFlowGraph");
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
+                                                 "BuildFlowGraph"));
         flow_graph = pipeline->BuildFlowGraph(
             zone, parsed_function(), ic_data_array, osr_id(), optimized());
       }
@@ -637,8 +638,8 @@
       const bool reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized());
       if (reorder_blocks) {
-        TIMELINE_DURATION(thread(), Compiler,
-                          "BlockScheduler::AssignEdgeWeights");
+        NOT_IN_PRODUCT(TimelineDurationScope tds(
+            thread(), compiler_timeline, "BlockScheduler::AssignEdgeWeights"));
         block_scheduler.AssignEdgeWeights();
       }
 
@@ -648,7 +649,8 @@
       pass_state.reorder_blocks = reorder_blocks;
 
       if (optimized()) {
-        TIMELINE_DURATION(thread(), Compiler, "OptimizationPasses");
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
+                                                 "OptimizationPasses"));
 
         pass_state.inline_id_to_function.Add(&function);
         // We do not add the token position now because we don't know the
@@ -675,12 +677,14 @@
           pass_state.inline_id_to_token_pos, pass_state.caller_inline_id,
           ic_data_array);
       {
-        TIMELINE_DURATION(thread(), Compiler, "CompileGraph");
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
+                                                 "CompileGraph"));
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation(flow_graph);
       }
       {
-        TIMELINE_DURATION(thread(), Compiler, "FinalizeCompilation");
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
+                                                 "FinalizeCompilation"));
         if (thread()->IsMutatorThread()) {
           *result =
               FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
@@ -1201,7 +1205,7 @@
     // it now, but don't bother remembering it because it won't be used again.
     ASSERT(!field.HasPrecompiledInitializer());
     {
-#if defined(SUPPORT_TIMELINE)
+#if !defined(PRODUCT)
       VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
       TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
                                 "CompileStaticInitializer");
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 8dbd0e1..a951991 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -164,10 +164,11 @@
   start_time_micros_ = OS::GetCurrentMonotonicMicros();
   VirtualMemory::Init();
   OSThread::Init();
-#if defined(SUPPORT_TIMELINE)
-  Timeline::Init();
-  TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::Init");
-#endif
+  if (FLAG_support_timeline) {
+    Timeline::Init();
+  }
+  NOT_IN_PRODUCT(
+      TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::Init"));
   Isolate::InitVM();
   PortMap::Init();
   FreeListElement::Init();
@@ -213,9 +214,8 @@
     ArgumentsDescriptor::Init();
     ICData::Init();
     if (vm_isolate_snapshot != NULL) {
-#if defined(SUPPORT_TIMELINE)
-      TimelineDurationScope tds(Timeline::GetVMStream(), "VMIsolateSnapshot");
-#endif
+      NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
+                                               "VMIsolateSnapshot"));
       const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot);
       if (snapshot == NULL) {
         return strdup("Invalid vm isolate snapshot seen");
@@ -260,7 +260,7 @@
       ReversePcLookupCache::BuildAndAttachToIsolate(vm_isolate_);
 
       Object::FinishInit(vm_isolate_);
-#if defined(SUPPORT_TIMELINE)
+#if !defined(PRODUCT)
       if (tds.enabled()) {
         tds.SetNumArguments(2);
         tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
@@ -309,9 +309,8 @@
     }
 #endif
     {
-#if defined(SUPPORT_TIMELINE)
-      TimelineDurationScope tds(Timeline::GetVMStream(), "FinalizeVMIsolate");
-#endif
+      NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
+                                               "FinalizeVMIsolate"));
       Object::FinalizeVMIsolate(vm_isolate_);
     }
 #if defined(DEBUG)
@@ -527,13 +526,13 @@
                  UptimeMillis());
   }
   NOT_IN_PRODUCT(CodeObservers::Cleanup());
-#if defined(SUPPORT_TIMELINE)
-  if (FLAG_trace_shutdown) {
-    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n",
-                 UptimeMillis());
+  if (FLAG_support_timeline) {
+    if (FLAG_trace_shutdown) {
+      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n",
+                   UptimeMillis());
+    }
+    Timeline::Cleanup();
   }
-  Timeline::Cleanup();
-#endif
   OS::Cleanup();
   if (FLAG_trace_shutdown) {
     OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Done\n", UptimeMillis());
@@ -572,17 +571,16 @@
   // Initialize the new isolate.
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
-#if defined(SUPPORT_TIMLINE)
-  TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
-                            "InitializeIsolate");
-  tds.SetNumArguments(1);
-  tds.CopyArgument(0, "isolateName", I->name());
-#endif
+  NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
+                                           "InitializeIsolate");
+                 tds.SetNumArguments(1);
+                 tds.CopyArgument(0, "isolateName", I->name());)
   ASSERT(I != NULL);
   StackZone zone(T);
   HandleScope handle_scope(T);
   {
-    TIMELINE_DURATION(T, Isolate, "ObjectStore::Init");
+    NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
+                                             "ObjectStore::Init"));
     ObjectStore::Init(I);
   }
 
@@ -593,10 +591,8 @@
   }
   if ((snapshot_data != NULL) && kernel_buffer == NULL) {
     // Read the snapshot and setup the initial state.
-#if defined(SUPPORT_TIMELINE)
-    TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
-                              "IsolateSnapshotReader");
-#endif
+    NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
+                                             "IsolateSnapshotReader"));
     // TODO(turnidge): Remove once length is not part of the snapshot.
     const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
     if (snapshot == NULL) {
@@ -622,7 +618,7 @@
 
     ReversePcLookupCache::BuildAndAttachToIsolate(I);
 
-#if defined(SUPPORT_TIMELINE)
+#if !defined(PRODUCT)
     if (tds.enabled()) {
       tds.SetNumArguments(2);
       tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 9d7c192..b01af49 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -4763,14 +4763,6 @@
 #endif
     }
 
-    if (name.Equals(Symbols::DartDeveloperTimeline())) {
-#ifdef SUPPORT_TIMELINE
-      return Symbols::True().raw();
-#else
-      return Symbols::False().raw();
-#endif
-    }
-
     const String& prefix = Symbols::DartLibrary();
     if (name.StartsWith(prefix)) {
       const String& library_name =
@@ -5693,7 +5685,9 @@
 }
 
 DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) {
-#if defined(SUPPORT_TIMELINE)
+  if (!FLAG_support_timeline) {
+    return;
+  }
   const bool api_enabled = (stream_mask & DART_TIMELINE_STREAM_API) != 0;
   const bool compiler_enabled =
       (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0;
@@ -5714,7 +5708,6 @@
   Timeline::SetStreamGCEnabled(gc_enabled);
   Timeline::SetStreamIsolateEnabled(isolate_enabled);
   Timeline::SetStreamVMEnabled(vm_enabled);
-#endif
 }
 
 static void StartStreamToConsumer(Dart_StreamConsumer consumer,
@@ -5795,17 +5788,18 @@
 DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
     Dart_EmbedderTimelineStartRecording start_recording,
     Dart_EmbedderTimelineStopRecording stop_recording) {
-#if defined(SUPPORT_TIMELINE)
+  if (!FLAG_support_timeline) {
+    return;
+  }
   Timeline::set_start_recording_cb(start_recording);
   Timeline::set_stop_recording_cb(stop_recording);
-#endif
 }
 
 DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
                                              void* user_data) {
-#if defined(PRODUCT)
-  return false;
-#else
+  if (!FLAG_support_timeline) {
+    return false;
+  }
   // To support various embedders, it must be possible to call this function
   // from a thread for which we have not entered an Isolate and set up a Thread
   // TLS object. Therefore, a Zone may not be available, a StackZone cannot be
@@ -5829,7 +5823,6 @@
   }
   FinishStreamToConsumer(consumer, user_data, "timeline");
   return success;
-#endif
 }
 
 DART_EXPORT void Dart_TimelineEvent(const char* label,
@@ -5839,7 +5832,9 @@
                                     intptr_t argument_count,
                                     const char** argument_names,
                                     const char** argument_values) {
-#if defined(SUPPORT_TIMELINE)
+  if (!FLAG_support_timeline) {
+    return;
+  }
   if (type < Dart_Timeline_Event_Begin) {
     return;
   }
@@ -5896,7 +5891,6 @@
     event->CopyArgument(i, argument_names[i], argument_values[i]);
   }
   event->Complete();
-#endif
 }
 #endif  // defined(PRODUCT)
 
@@ -6055,7 +6049,8 @@
   ASSERT(FLAG_load_deferred_eagerly);
   CHECK_NULL(callback);
 
-  TIMELINE_DURATION(T, Isolate, "WriteAppAOTSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
+                                            "WriteAppAOTSnapshot"));
   AssemblyImageWriter image_writer(T, callback, callback_data, NULL, NULL);
   uint8_t* vm_snapshot_data_buffer = NULL;
   uint8_t* isolate_snapshot_data_buffer = NULL;
@@ -6087,7 +6082,8 @@
   API_TIMELINE_DURATION(T);
   CHECK_NULL(callback);
 
-  TIMELINE_DURATION(T, Isolate, "WriteVMAOTSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
+                                            "WriteVMAOTSnapshot"));
   AssemblyImageWriter image_writer(T, callback, callback_data, NULL, NULL);
   uint8_t* vm_snapshot_data_buffer = NULL;
   FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data_buffer, NULL,
@@ -6142,7 +6138,8 @@
   }
   const void* shared_instructions_image = shared_instructions;
 
-  TIMELINE_DURATION(T, Isolate, "WriteAppAOTSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
+                                            "WriteAppAOTSnapshot"));
   BlobImageWriter vm_image_writer(T, vm_snapshot_instructions_buffer,
                                   ApiReallocate, 2 * MB /* initial_size */,
                                   /*shared_objects=*/nullptr,
@@ -6253,7 +6250,8 @@
   ProgramVisitor::Dedup();
   Symbols::Compact(I);
 
-  TIMELINE_DURATION(T, Isolate, "WriteCoreJITSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
+                                            "WriteCoreJITSnapshot"));
   BlobImageWriter vm_image_writer(T, vm_snapshot_instructions_buffer,
                                   ApiReallocate, 2 * MB /* initial_size */,
                                   /*shared_objects=*/nullptr,
@@ -6321,7 +6319,8 @@
     DumpTypeArgumentsTable(I);
   }
 
-  TIMELINE_DURATION(T, Isolate, "WriteAppJITSnapshot");
+  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
+                                            "WriteAppJITSnapshot"));
   BlobImageWriter isolate_image_writer(T, isolate_snapshot_instructions_buffer,
                                        ApiReallocate, 2 * MB /* initial_size */,
                                        /*shared_objects=*/nullptr,
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 261fd73..8d91094 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -102,7 +102,7 @@
     }                                                                          \
   } while (0)
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
 #define API_TIMELINE_DURATION(thread)                                          \
   TimelineDurationScope tds(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
 #define API_TIMELINE_DURATION_BASIC(thread)                                    \
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 0a1a227..f78316d 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -3111,7 +3111,8 @@
   {
     Thread* thread = Thread::Current();
     DisableThreadInterruptsScope dtis(thread);
-    TIMELINE_DURATION(thread, Debugger, "Debugger Pause");
+    TimelineDurationScope tds(thread, Timeline::GetDebuggerStream(),
+                              "Debugger Pause");
 
     // Send the pause event.
     Service::HandleEvent(event);
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 02d2991..0f499e1 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -155,9 +155,8 @@
   delete[] deferred_objects_;
   deferred_objects_ = NULL;
   deferred_objects_count_ = 0;
-
-#if defined(SUPPORT_TIMELINE)
-  if (deopt_start_micros_ != 0) {
+#ifndef PRODUCT
+  if (FLAG_support_timeline && (deopt_start_micros_ != 0)) {
     TimelineStream* compiler_stream = Timeline::GetCompilerStream();
     ASSERT(compiler_stream != NULL);
     if (compiler_stream->enabled()) {
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 1f6cb3b..d11e203 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -161,6 +161,7 @@
   R(support_il_printer, false, bool, true, "Support the IL printer.")          \
   C(support_reload, false, false, bool, true, "Support isolate reload.")       \
   R(support_service, false, bool, true, "Support the service protocol.")       \
+  R(support_timeline, false, bool, true, "Support timeline.")                  \
   D(trace_cha, bool, false, "Trace CHA operations")                            \
   R(trace_field_guards, false, bool, false, "Trace changes in field's cids.")  \
   D(trace_ic, bool, false, "Trace IC handling")                                \
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index ad33a42..0e7e1cd 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -73,10 +73,6 @@
 #define NOT_IN_PRECOMPILED(code) code
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-#if !defined(PRODUCT) || defined(HOST_OS_FUCHSIA) || defined(TARGET_OS_FUCHSIA)
-#define SUPPORT_TIMELINE 1
-#endif
-
 #if defined(ARCH_IS_64_BIT)
 #define HASH_IN_OBJECT_HEADER 1
 #endif
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 6855871..859174e 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -293,9 +293,7 @@
   bool result =
       Thread::EnterIsolateAsHelper(isolate_, Thread::kCompactorTask, true);
   ASSERT(result);
-#ifdef SUPPORT_TIMELINE
-  Thread* thread = Thread::Current();
-#endif
+  NOT_IN_PRODUCT(Thread* thread = Thread::Current());
   {
     {
       TIMELINE_FUNCTION_GC_DURATION(thread, "Plan");
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index a3dca1f..b07afe9 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -603,9 +603,7 @@
 }
 
 void Scavenger::IterateRoots(Isolate* isolate, ScavengerVisitor* visitor) {
-#ifdef SUPPORT_TIMELINE
-  Thread* thread = Thread::Current();
-#endif
+  NOT_IN_PRODUCT(Thread* thread = Thread::Current());
   int64_t start = OS::GetCurrentMonotonicMicros();
   {
     TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessRoots");
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index d581938..9be1458 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -272,7 +272,8 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Heap* heap = thread->isolate()->heap();
-  TIMELINE_DURATION(thread, Isolate, "WriteInstructions");
+  NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
+                                           "WriteInstructions"));
 
   // Handlify collected raw pointers as building the names below
   // will allocate on the Dart heap.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 1eabad4..7f1e8a2 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -496,7 +496,7 @@
   StackZone stack_zone(thread);
   Zone* zone = stack_zone.GetZone();
   HandleScope handle_scope(thread);
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
   TimelineDurationScope tds(
       thread, Timeline::GetIsolateStream(),
       message->IsOOB() ? "HandleOOBMessage" : "HandleMessage");
@@ -1359,16 +1359,16 @@
     ASSERT(this == state->isolate());
     Run();
   }
-#if defined(SUPPORT_TIMELINE)
-  TimelineStream* stream = Timeline::GetIsolateStream();
-  ASSERT(stream != NULL);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != NULL) {
-    event->Instant("Runnable");
-    event->Complete();
-  }
-#endif
 #ifndef PRODUCT
+  if (FLAG_support_timeline) {
+    TimelineStream* stream = Timeline::GetIsolateStream();
+    ASSERT(stream != NULL);
+    TimelineEvent* event = stream->StartEvent();
+    if (event != NULL) {
+      event->Instant("Runnable");
+      event->Complete();
+    }
+  }
   if (FLAG_support_service && !Isolate::IsVMInternalIsolate(this) &&
       Service::isolate_stream.enabled()) {
     ServiceEvent runnableEvent(this, ServiceEvent::kIsolateRunnable);
@@ -1815,15 +1815,15 @@
   // Fail fast if anybody tries to post any more messages to this isolate.
   delete message_handler();
   set_message_handler(NULL);
-#if defined(SUPPORT_TIMELINE)
-  // Before analyzing the isolate's timeline blocks- reclaim all cached
-  // blocks.
-  Timeline::ReclaimCachedBlocksFromThreads();
-#endif
+  if (FLAG_support_timeline) {
+    // Before analyzing the isolate's timeline blocks- reclaim all cached
+    // blocks.
+    Timeline::ReclaimCachedBlocksFromThreads();
+  }
 
 // Dump all timing data for the isolate.
-#if defined(SUPPORT_TIMELINE) && !defined(PRODUCT)
-  if (FLAG_timing) {
+#ifndef PRODUCT
+  if (FLAG_support_timeline && FLAG_timing) {
     TimelinePauseTrace tpt;
     tpt.Print();
   }
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index ab90491..693078c 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -71,9 +71,9 @@
  public:
   virtual void Run() {
     ASSERT(Isolate::Current() == NULL);
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
     TimelineDurationScope tds(Timeline::GetVMStream(), "KernelIsolateStartup");
-#endif  // SUPPORT_TIMELINE
+#endif  // !PRODUCT
     char* error = NULL;
     Isolate* isolate = NULL;
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 43c0a3c..e680342 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1299,7 +1299,8 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   const bool is_kernel = (kernel_buffer != NULL);
 #endif
-  TIMELINE_DURATION(thread, Isolate, "Object::Init");
+  NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
+                                           "Object::Init");)
 
 #if defined(DART_NO_SNAPSHOT)
   bool bootstrapping =
diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc
index fa5e8ea..22abcbb 100644
--- a/runtime/vm/os_thread.cc
+++ b/runtime/vm/os_thread.cc
@@ -29,7 +29,7 @@
 #if defined(DEBUG)
       join_id_(kInvalidThreadJoinId),
 #endif
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
       trace_id_(OSThread::GetCurrentThreadTraceId()),
 #endif
       name_(NULL),
@@ -75,11 +75,11 @@
   RemoveThreadFromList(this);
   delete log_;
   log_ = NULL;
-#if defined(SUPPORT_TIMELINE)
-  if (Timeline::recorder() != NULL) {
-    Timeline::recorder()->FinishBlock(timeline_block_);
+  if (FLAG_support_timeline) {
+    if (Timeline::recorder() != NULL) {
+      Timeline::recorder()->FinishBlock(timeline_block_);
+    }
   }
-#endif
   timeline_block_ = NULL;
   delete timeline_block_lock_;
   free(name_);
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index 811bb07..1fcf0da 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -69,7 +69,7 @@
     return id_;
   }
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
   ThreadId trace_id() const {
     ASSERT(trace_id_ != OSThread::kInvalidThreadId);
     return trace_id_;
@@ -230,7 +230,7 @@
   void set_thread(ThreadState* value) { thread_ = value; }
 
   static void Cleanup();
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
   static ThreadId GetCurrentThreadTraceId();
 #endif  // PRODUCT
   static OSThread* GetOSThreadFromThread(ThreadState* thread);
@@ -246,7 +246,7 @@
   // only called once per OSThread.
   ThreadJoinId join_id_;
 #endif
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
   const ThreadId trace_id_;  // Used to interface with tracing tools.
 #endif
   char* name_;  // A name for this thread.
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index e03d9b7..5eab0b8 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -187,7 +187,7 @@
   return gettid();
 }
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return GetCurrentThreadId();
 }
diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc
index b465e07..cae2552 100644
--- a/runtime/vm/os_thread_fuchsia.cc
+++ b/runtime/vm/os_thread_fuchsia.cc
@@ -175,7 +175,7 @@
   return info.koid;
 }
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return pthread_self();
 }
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index 8c9fa0f..4b8da4d 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -189,7 +189,7 @@
   return pthread_self();
 }
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return syscall(__NR_gettid);
 }
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index 0fff6fd..39f0047 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -165,7 +165,7 @@
   return pthread_self();
 }
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return ThreadIdFromIntPtr(pthread_mach_thread_np(pthread_self()));
 }
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index b1aed90..56b5e2f 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -114,7 +114,7 @@
   return ::GetCurrentThreadId();
 }
 
-#ifdef SUPPORT_TIMELINE
+#ifndef PRODUCT
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return ::GetCurrentThreadId();
 }
diff --git a/runtime/vm/regexp_assembler_bytecode.cc b/runtime/vm/regexp_assembler_bytecode.cc
index f63bfec..3847c62 100644
--- a/runtime/vm/regexp_assembler_bytecode.cc
+++ b/runtime/vm/regexp_assembler_bytecode.cc
@@ -419,7 +419,7 @@
 
   if (regexp.bytecode(is_one_byte, sticky) == TypedData::null()) {
     const String& pattern = String::Handle(zone, regexp.pattern());
-#if defined(SUPPORT_TIMELINE)
+#if !defined(PRODUCT)
     TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
                               "CompileIrregexpBytecode");
     if (tds.enabled()) {
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index e12ce31..580d290 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3526,7 +3526,6 @@
     NULL,
 };
 
-#if defined(SUPPORT_TIMELINE)
 static bool HasStream(const char** recorded_streams, const char* stream) {
   while (*recorded_streams != NULL) {
     if ((strstr(*recorded_streams, "all") != NULL) ||
@@ -3537,13 +3536,12 @@
   }
   return false;
 }
-#endif
 
 static bool SetVMTimelineFlags(Thread* thread, JSONStream* js) {
-#if !defined(SUPPORT_TIMELINE)
-  PrintSuccess(js);
-  return true;
-#else
+  if (!FLAG_support_timeline) {
+    PrintSuccess(js);
+    return true;
+  }
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   StackZone zone(thread);
@@ -3563,7 +3561,6 @@
   PrintSuccess(js);
 
   return true;
-#endif
 }
 
 static const MethodParameter* get_vm_timeline_flags_params[] = {
@@ -3571,17 +3568,16 @@
 };
 
 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) {
-#if !defined(SUPPORT_TIMELINE)
-  JSONObject obj(js);
-  obj.AddProperty("type", "TimelineFlags");
-  return true;
-#else
+  if (!FLAG_support_timeline) {
+    JSONObject obj(js);
+    obj.AddProperty("type", "TimelineFlags");
+    return true;
+  }
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   StackZone zone(thread);
   Timeline::PrintFlagsToJSON(js);
   return true;
-#endif
 }
 
 static const MethodParameter* clear_vm_timeline_params[] = {
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 3f7c827..8d13ec6 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -313,9 +313,9 @@
  public:
   virtual void Run() {
     ASSERT(Isolate::Current() == NULL);
-#if defined(SUPPORT_TIMELINE)
+#ifndef PRODUCT
     TimelineDurationScope tds(Timeline::GetVMStream(), "ServiceIsolateStartup");
-#endif  // SUPPORT_TIMELINE
+#endif  // !PRODUCT
     char* error = NULL;
     Isolate* isolate = NULL;
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index f057703..536ad2b 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -380,7 +380,6 @@
   V(DartVMService, "dart:_vmservice")                                          \
   V(DartIOLibName, "dart.io")                                                  \
   V(DartVMProduct, "dart.vm.product")                                          \
-  V(DartDeveloperTimeline, "dart.developer.timeline")                          \
   V(EvalSourceUri, "evaluate:source")                                          \
   V(ExternalName, "ExternalName")                                              \
   V(_Random, "_Random")                                                        \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index d4b98cc..8756113 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -106,7 +106,7 @@
       interpreter_(nullptr),
 #endif
       next_(NULL) {
-#if defined(SUPPORT_TIMELINE)
+#if !defined(PRODUCT)
   dart_stream_ = Timeline::GetDartStream();
   ASSERT(dart_stream_ != NULL);
 #endif
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index e26ff04..e343cdd 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
-#if defined(SUPPORT_TIMELINE)
+#include "platform/globals.h"
+#ifndef PRODUCT
 
 #include "vm/timeline.h"
 
@@ -239,11 +239,9 @@
     Timeline::get_stop_recording_cb()();
   }
 
-#ifndef PRODUCT
   if (FLAG_timeline_dir != NULL) {
     recorder_->WriteTo(FLAG_timeline_dir);
   }
-#endif
 
 // Disable global streams.
 #define TIMELINE_STREAM_DISABLE(name, not_used)                                \
@@ -283,7 +281,6 @@
   }
 }
 
-#ifndef PRODUCT
 void Timeline::PrintFlagsToJSON(JSONStream* js) {
   JSONObject obj(js);
   obj.AddProperty("type", "TimelineFlags");
@@ -309,7 +306,6 @@
 #undef ADD_RECORDED_STREAM_NAME
   }
 }
-#endif
 
 void Timeline::Clear() {
   TimelineEventRecorder* recorder = Timeline::recorder();
@@ -625,7 +621,6 @@
   return (delta >= 0) && (delta <= time_extent_micros);
 }
 
-#ifndef PRODUCT
 void TimelineEvent::PrintJSON(JSONStream* stream) const {
   if (!FLAG_support_service) {
     return;
@@ -717,7 +712,6 @@
     }
   }
 }
-#endif
 
 int64_t TimelineEvent::TimeOrigin() const {
   return timestamp0_;
@@ -866,7 +860,7 @@
 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(stream, label) {
-  if (!enabled()) {
+  if (!FLAG_support_timeline || !enabled()) {
     return;
   }
   timestamp_ = OS::GetCurrentMonotonicMicros();
@@ -877,7 +871,7 @@
                                              TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(thread, stream, label) {
-  if (!enabled()) {
+  if (!FLAG_support_timeline || !enabled()) {
     return;
   }
   timestamp_ = OS::GetCurrentMonotonicMicros();
@@ -885,6 +879,9 @@
 }
 
 TimelineDurationScope::~TimelineDurationScope() {
+  if (!FLAG_support_timeline) {
+    return;
+  }
   if (!ShouldEmitEvent()) {
     return;
   }
@@ -904,6 +901,9 @@
 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(stream, label) {
+  if (!FLAG_support_timeline) {
+    return;
+  }
   EmitBegin();
 }
 
@@ -911,14 +911,23 @@
                                              TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(thread, stream, label) {
+  if (!FLAG_support_timeline) {
+    return;
+  }
   EmitBegin();
 }
 
 TimelineBeginEndScope::~TimelineBeginEndScope() {
+  if (!FLAG_support_timeline) {
+    return;
+  }
   EmitEnd();
 }
 
 void TimelineBeginEndScope::EmitBegin() {
+  if (!FLAG_support_timeline) {
+    return;
+  }
   if (!ShouldEmitEvent()) {
     return;
   }
@@ -935,6 +944,9 @@
 }
 
 void TimelineBeginEndScope::EmitEnd() {
+  if (!FLAG_support_timeline) {
+    return;
+  }
   if (!ShouldEmitEvent()) {
     return;
   }
@@ -971,7 +983,6 @@
 TimelineEventRecorder::TimelineEventRecorder()
     : async_id_(0), time_low_micros_(0), time_high_micros_(0) {}
 
-#ifndef PRODUCT
 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
   if (!FLAG_support_service) {
     return;
@@ -998,7 +1009,6 @@
     }
   }
 }
-#endif
 
 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
   // Grab the current thread.
@@ -1095,7 +1105,6 @@
   thread_block_lock->Unlock();
 }
 
-#ifndef PRODUCT
 void TimelineEventRecorder::WriteTo(const char* directory) {
   if (!FLAG_support_service) {
     return;
@@ -1134,7 +1143,6 @@
 
   return;
 }
-#endif
 
 int64_t TimelineEventRecorder::GetNextAsyncId() {
   // TODO(johnmccutchan): Gracefully handle wrap around.
@@ -1187,7 +1195,6 @@
   delete memory_;
 }
 
-#ifndef PRODUCT
 void TimelineEventFixedBufferRecorder::PrintJSONEvents(
     JSONArray* events,
     TimelineEventFilter* filter) {
@@ -1246,7 +1253,6 @@
   PrintJSONMeta(&events);
   PrintJSONEvents(&events, filter);
 }
-#endif
 
 TimelineEventBlock* TimelineEventFixedBufferRecorder::GetHeadBlockLocked() {
   return &blocks_[0];
@@ -1314,7 +1320,6 @@
 
 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {}
 
-#ifndef PRODUCT
 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js,
                                               TimelineEventFilter* filter) {
   if (!FLAG_support_service) {
@@ -1336,7 +1341,6 @@
   }
   JSONArray events(js);
 }
-#endif
 
 TimelineEvent* TimelineEventCallbackRecorder::StartEvent() {
   TimelineEvent* event = new TimelineEvent();
@@ -1352,7 +1356,6 @@
 
 TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
 
-#ifndef PRODUCT
 void TimelineEventPlatformRecorder::PrintJSON(JSONStream* js,
                                               TimelineEventFilter* filter) {
   if (!FLAG_support_service) {
@@ -1374,7 +1377,6 @@
   }
   JSONArray events(js);
 }
-#endif
 
 TimelineEvent* TimelineEventPlatformRecorder::StartEvent() {
   TimelineEvent* event = new TimelineEvent();
@@ -1400,7 +1402,6 @@
   }
 }
 
-#ifndef PRODUCT
 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
                                              TimelineEventFilter* filter) {
   if (!FLAG_support_service) {
@@ -1427,7 +1428,6 @@
   PrintJSONMeta(&events);
   PrintJSONEvents(&events, filter);
 }
-#endif
 
 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
   return head_;
@@ -1455,7 +1455,6 @@
   return head_;
 }
 
-#ifndef PRODUCT
 static int TimelineEventBlockCompare(TimelineEventBlock* const* a,
                                      TimelineEventBlock* const* b) {
   return (*a)->LowerTimeBound() - (*b)->LowerTimeBound();
@@ -1501,7 +1500,6 @@
     }
   }
 }
-#endif
 
 void TimelineEventEndlessRecorder::Clear() {
   TimelineEventBlock* current = head_;
@@ -1527,7 +1525,6 @@
   Reset();
 }
 
-#ifndef PRODUCT
 void TimelineEventBlock::PrintJSON(JSONStream* js) const {
   ASSERT(!in_use());
   JSONArray events(js);
@@ -1536,7 +1533,6 @@
     events.AddValue(event);
   }
 }
-#endif
 
 TimelineEvent* TimelineEventBlock::StartEvent() {
   ASSERT(!IsFull());
@@ -1602,13 +1598,11 @@
     OS::PrintErr("Finish block %p\n", this);
   }
   in_use_ = false;
-#ifndef PRODUCT
   if (Service::timeline_stream.enabled()) {
     ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents);
     service_event.set_timeline_event_block(this);
     Service::HandleEvent(&service_event);
   }
-#endif
 }
 
 TimelineEventBlockIterator::TimelineEventBlockIterator(
@@ -1733,4 +1727,4 @@
 
 }  // namespace dart
 
-#endif  // defined(SUPPORT_TIMELINE)
+#endif  // !PRODUCT
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 55a5db0..92f33a3 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -89,10 +89,8 @@
 
   static void Clear();
 
-#ifndef PRODUCT
   // Print information about streams to JSON.
   static void PrintFlagsToJSON(JSONStream* json);
-#endif
 
 #define TIMELINE_STREAM_ACCESSOR(name, not_used)                               \
   static TimelineStream* Get##name##Stream() { return &stream_##name##_; }
@@ -313,9 +311,7 @@
   // The highest time value stored in this event.
   int64_t HighTime() const;
 
-#ifndef PRODUCT
   void PrintJSON(JSONStream* stream) const;
-#endif
 
   ThreadId thread() const { return thread_; }
 
@@ -451,9 +447,7 @@
   DISALLOW_COPY_AND_ASSIGN(TimelineEvent);
 };
 
-#ifdef SUPPORT_TIMELINE
-#define TIMELINE_DURATION(thread, stream, name)                                \
-  TimelineDurationScope(thread, Timeline::Get##stream##Stream(), name);
+#ifndef PRODUCT
 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function)         \
   TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), name);      \
   if (tds.enabled()) {                                                         \
@@ -469,7 +463,6 @@
   tds.SetNumArguments(1);                                                      \
   tds.CopyArgument(0, "mode", "basic");
 #else
-#define TIMELINE_DURATION(thread, stream, name)
 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function)
 #define TIMELINE_FUNCTION_GC_DURATION(thread, name)
 #define TIMELINE_FUNCTION_GC_DURATION_BASIC(thread, name)
@@ -605,9 +598,7 @@
   ThreadId thread_id() const { return thread_id_; }
 
  protected:
-#ifndef PRODUCT
   void PrintJSON(JSONStream* stream) const;
-#endif
 
   TimelineEvent* StartEvent();
 
@@ -698,19 +689,15 @@
   TimelineEventBlock* GetNewBlock();
 
   // Interface method(s) which must be implemented.
-#ifndef PRODUCT
   virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0;
   virtual void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) = 0;
-#endif
   virtual const char* name() const = 0;
   int64_t GetNextAsyncId();
 
   void FinishBlock(TimelineEventBlock* block);
 
  protected:
-#ifndef PRODUCT
   void WriteTo(const char* directory);
-#endif
 
   // Interface method(s) which must be implemented.
   virtual TimelineEvent* StartEvent() = 0;
@@ -720,9 +707,7 @@
   virtual void Clear() = 0;
 
   // Utility method(s).
-#ifndef PRODUCT
   void PrintJSONMeta(JSONArray* array) const;
-#endif
   TimelineEvent* ThreadBlockStartEvent();
   void ThreadBlockCompleteEvent(TimelineEvent* event);
 
@@ -754,10 +739,8 @@
   explicit TimelineEventFixedBufferRecorder(intptr_t capacity);
   virtual ~TimelineEventFixedBufferRecorder();
 
-#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
-#endif
 
  protected:
   TimelineEvent* StartEvent();
@@ -766,9 +749,7 @@
   intptr_t FindOldestBlockIndex() const;
   void Clear();
 
-#ifndef PRODUCT
   void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
-#endif
 
   VirtualMemory* memory_;
   TimelineEventBlock* blocks_;
@@ -812,10 +793,8 @@
   TimelineEventCallbackRecorder();
   virtual ~TimelineEventCallbackRecorder();
 
-#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
-#endif
 
   // Called when |event| is completed. It is unsafe to keep a reference to
   // |event| as it may be freed as soon as this function returns.
@@ -839,10 +818,8 @@
   TimelineEventEndlessRecorder();
   virtual ~TimelineEventEndlessRecorder();
 
-#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
-#endif
 
   const char* name() const { return "Endless"; }
 
@@ -853,9 +830,7 @@
   TimelineEventBlock* GetHeadBlockLocked();
   void Clear();
 
-#ifndef PRODUCT
   void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
-#endif
 
   TimelineEventBlock* head_;
   intptr_t block_index_;
@@ -890,10 +865,8 @@
   TimelineEventPlatformRecorder();
   virtual ~TimelineEventPlatformRecorder();
 
-#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
-#endif
 
   // Called when |event| is completed. It is unsafe to keep a reference to
   // |event| as it may be freed as soon as this function returns.
diff --git a/runtime/vm/timeline_android.cc b/runtime/vm/timeline_android.cc
index 5ca038b..cd316eb 100644
--- a/runtime/vm/timeline_android.cc
+++ b/runtime/vm/timeline_android.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
-#if defined(HOST_OS_ANDROID) && defined(SUPPORT_TIMELINE)
+#include "platform/globals.h"
+#if defined(HOST_OS_ANDROID) && !defined(PRODUCT)
 
 #include <errno.h>
 #include <fcntl.h>
diff --git a/runtime/vm/timeline_fuchsia.cc b/runtime/vm/timeline_fuchsia.cc
index 9c0dab4..f39cc20 100644
--- a/runtime/vm/timeline_fuchsia.cc
+++ b/runtime/vm/timeline_fuchsia.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
-#if defined(HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE)
+#include "platform/globals.h"
+#if defined(HOST_OS_FUCHSIA) && !defined(PRODUCT)
 
 #include <trace-engine/context.h>
 #include <trace-engine/instrumentation.h>
diff --git a/runtime/vm/timeline_linux.cc b/runtime/vm/timeline_linux.cc
index ed9ff7f..c1c5d53 100644
--- a/runtime/vm/timeline_linux.cc
+++ b/runtime/vm/timeline_linux.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
-#if defined(HOST_OS_LINUX) && defined(SUPPORT_TIMELINE)
+#include "platform/globals.h"
+#if defined(HOST_OS_LINUX) && !defined(PRODUCT)
 
 #include <errno.h>
 #include <fcntl.h>
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index fcc776e..37ae997 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -4,7 +4,7 @@
 
 part of dart.developer;
 
-const bool _hasTimeline = const bool.fromEnvironment("dart.developer.timeline");
+const bool _isProduct = const bool.fromEnvironment("dart.vm.product");
 
 /// A typedef for the function argument to [Timeline.timeSync].
 typedef dynamic TimelineSyncFunction();
@@ -100,7 +100,7 @@
   /// a [Flow] event. This operation must be finished before
   /// returning to the event queue.
   static void startSync(String name, {Map arguments, Flow flow}) {
-    if (!_hasTimeline) return;
+    if (_isProduct) return;
     ArgumentError.checkNotNull(name, 'name');
     if (!_isDartStreamEnabled()) {
       // Push a null onto the stack and return.
@@ -119,7 +119,7 @@
 
   /// Finish the last synchronous operation that was started.
   static void finishSync() {
-    if (!_hasTimeline) {
+    if (_isProduct) {
       return;
     }
     if (_stack.length == 0) {
@@ -137,7 +137,7 @@
 
   /// Emit an instant event.
   static void instantSync(String name, {Map arguments}) {
-    if (!_hasTimeline) return;
+    if (_isProduct) return;
     ArgumentError.checkNotNull(name, 'name');
     if (!_isDartStreamEnabled()) {
       // Stream is disabled.
@@ -187,7 +187,7 @@
   /// Start a synchronous operation within this task named [name].
   /// Optionally takes a [Map] of [arguments].
   void start(String name, {Map arguments}) {
-    if (!_hasTimeline) return;
+    if (_isProduct) return;
     ArgumentError.checkNotNull(name, 'name');
     var block = new _AsyncBlock._(name, _taskId);
     if (arguments != null) {
@@ -199,7 +199,7 @@
 
   /// Emit an instant event for this task.
   void instant(String name, {Map arguments}) {
-    if (!_hasTimeline) return;
+    if (_isProduct) return;
     ArgumentError.checkNotNull(name, 'name');
     Map instantArguments;
     if (arguments != null) {
@@ -211,7 +211,7 @@
 
   /// Finish the last synchronous operation that was started.
   void finish() {
-    if (!_hasTimeline) {
+    if (_isProduct) {
       return;
     }
     if (_stack.length == 0) {