Version 1.3.0-dev.7.3

svn merge -c 34451 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 34464 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 34475 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 34489 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@34495 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 7a954ee..1427cba 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -1055,7 +1055,7 @@
   EmitREX_RB(dst, src);
   EmitUint8(0x0F);
   EmitUint8(0x5E);
-  EmitXmmRegisterOperand(dst & 6, src);
+  EmitXmmRegisterOperand(dst & 7, src);
 }
 
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index c0bbbe2..0d1e38e 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -515,6 +515,10 @@
           sinking->DetachMaterializations();
         }
 
+        // Compute and store graph informations (call & instruction counts)
+        // to be later used by the inliner.
+        FlowGraphInliner::CollectGraphInfo(flow_graph, true);
+
         // Perform register allocation on the SSA graph.
         FlowGraphAllocator allocator(*flow_graph);
         allocator.AllocateRegisters();
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 437366e..36be8de 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -47,7 +47,7 @@
     "default 10%: calls above-equal 10% of max-count are inlined.");
 DEFINE_FLAG(bool, inline_recursive, true,
     "Inline recursive calls.");
-DEFINE_FLAG(bool, print_inline_tree, false, "Print inlining tree");
+DEFINE_FLAG(bool, print_inlining_tree, false, "Print inlining tree");
 
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
@@ -136,7 +136,7 @@
           // parameters was fixed.
           // TODO(fschneider): Determine new heuristic parameters that avoid
           // these checks entirely.
-          if (!call->HasRecognizedTarget() &&
+          if (!call->HasSingleRecognizedTarget() &&
               (call->instance_call()->token_kind() != Token::kEQ)) {
             ++call_site_count_;
           }
@@ -154,6 +154,26 @@
 };
 
 
+// Structure for collecting inline data needed to print inlining tree.
+struct InlinedInfo {
+  const Function* caller;
+  const Function* inlined;
+  intptr_t inlined_depth;
+  const Definition* call_instr;
+  const char* bailout_reason;
+  InlinedInfo(const Function* caller_function,
+              const Function* inlined_function,
+              const intptr_t depth,
+              const Definition* call,
+              const char* reason = NULL)
+      : caller(caller_function),
+        inlined(inlined_function),
+        inlined_depth(depth),
+        call_instr(call),
+        bailout_reason(reason) {}
+};
+
+
 // A collection of call sites to consider for inlining.
 class CallSites : public ValueObject {
  public:
@@ -254,14 +274,16 @@
     }
   }
 
-  void FindCallSites(FlowGraph* graph, intptr_t depth) {
+  void FindCallSites(FlowGraph* graph,
+                     intptr_t depth,
+                     GrowableArray<InlinedInfo>* inlined_info) {
     ASSERT(graph != NULL);
-    // If depth is less than the threshold recursively add call sites.
+
     if (depth > FLAG_inlining_depth_threshold) return;
 
     // Recognized methods are not treated as normal calls. They don't have
     // calls in themselves, so we keep adding those even when at the threshold.
-    const bool only_recognized_methods =
+    const bool inline_only_recognized_methods =
         (depth == FLAG_inlining_depth_threshold);
 
     const intptr_t instance_call_start_ix = instance_calls_.length();
@@ -273,30 +295,44 @@
            !it.Done();
            it.Advance()) {
         Instruction* current = it.Current();
-        if (only_recognized_methods) {
+        if (current->IsPolymorphicInstanceCall()) {
           PolymorphicInstanceCallInstr* instance_call =
               current->AsPolymorphicInstanceCall();
-          if ((instance_call != NULL) && instance_call->HasRecognizedTarget()) {
+          if (!inline_only_recognized_methods ||
+              instance_call->HasSingleRecognizedTarget()) {
             instance_calls_.Add(InstanceCallInfo(instance_call, graph));
+          } else {
+            // Method not inlined because inlining too deep and method
+            // not recognized.
+            if (FLAG_print_inlining_tree) {
+              const Function* caller = &graph->parsed_function().function();
+              const Function* target =
+                  &Function::ZoneHandle(
+                      instance_call->ic_data().GetTargetAt(0));
+              inlined_info->Add(InlinedInfo(
+                  caller, target, depth, instance_call, "Too deep"));
+            }
           }
-          continue;
-        }
-        // Collect all call sites (!only_recognized_methods).
-        ClosureCallInstr* closure_call = current->AsClosureCall();
-        if (closure_call != NULL) {
-          closure_calls_.Add(ClosureCallInfo(closure_call, graph));
-          continue;
-        }
-        StaticCallInstr* static_call = current->AsStaticCall();
-        if (static_call != NULL) {
-          static_calls_.Add(StaticCallInfo(static_call, graph));
-          continue;
-        }
-        PolymorphicInstanceCallInstr* instance_call =
-            current->AsPolymorphicInstanceCall();
-        if (instance_call != NULL) {
-          instance_calls_.Add(InstanceCallInfo(instance_call, graph));
-          continue;
+        } else if (current->IsStaticCall()) {
+          StaticCallInstr* static_call = current->AsStaticCall();
+          if (!inline_only_recognized_methods ||
+              static_call->function().is_recognized()) {
+            static_calls_.Add(StaticCallInfo(static_call, graph));
+          } else {
+            // Method not inlined because inlining too deep and method
+            // not recognized.
+            if (FLAG_print_inlining_tree) {
+              const Function* caller = &graph->parsed_function().function();
+              const Function* target = &static_call->function();
+              inlined_info->Add(InlinedInfo(
+                  caller, target, depth, static_call, "Too deep"));
+            }
+          }
+        } else if (current->IsClosureCall()) {
+          if (!inline_only_recognized_methods) {
+            ClosureCallInstr* closure_call = current->AsClosureCall();
+            closure_calls_.Add(ClosureCallInfo(closure_call, graph));
+          }
         }
       }
     }
@@ -321,31 +357,14 @@
         callee_graph(NULL),
         parameter_stubs(NULL),
         exit_collector(NULL),
-        caller_(caller) { }
+        caller(caller) { }
 
   Definition* call;
   GrowableArray<Value*>* arguments;
   FlowGraph* callee_graph;
   ZoneGrowableArray<Definition*>* parameter_stubs;
   InlineExitCollector* exit_collector;
-  const Function& caller_;
-};
-
-
-// Structure for collecting inline data needed to print inlining tree.
-struct InlinedInfo {
-  const Function* caller;
-  const Function* inlined;
-  intptr_t inlined_depth;
-  const Definition* call_instr;
-  InlinedInfo(const Function* caller_function,
-              const Function* inlined_function,
-              const intptr_t depth,
-              const Definition* call)
-      : caller(caller_function),
-        inlined(inlined_function),
-        inlined_depth(depth),
-        call_instr(call) {}
+  const Function& caller;
 };
 
 
@@ -437,7 +456,9 @@
     collected_call_sites_ = &sites1;
     inlining_call_sites_ = &sites2;
     // Collect initial call sites.
-    collected_call_sites_->FindCallSites(caller_graph_, inlining_depth_);
+    collected_call_sites_->FindCallSites(caller_graph_,
+                                         inlining_depth_,
+                                         &inlined_info_);
     while (collected_call_sites_->HasCalls()) {
       TRACE_INLINING(OS::Print("  Depth %" Pd " ----------\n",
                                inlining_depth_));
@@ -475,6 +496,11 @@
     if (call_data->call->GetBlock()->try_index() !=
         CatchClauseNode::kInvalidTryIndex) {
       TRACE_INLINING(OS::Print("     Bailout: inside try-block\n"));
+      if (FLAG_print_inlining_tree) {
+        inlined_info_.Add(InlinedInfo(
+            &call_data->caller, &function, inlining_depth_, call_data->call,
+            "Inside try-block"));
+      }
       return false;
     }
 
@@ -484,6 +510,11 @@
     // Abort if the inlinable bit on the function is low.
     if (!function.IsInlineable()) {
       TRACE_INLINING(OS::Print("     Bailout: not inlinable\n"));
+      if (FLAG_print_inlining_tree) {
+        inlined_info_.Add(InlinedInfo(
+            &call_data->caller, &function, inlining_depth_, call_data->call,
+            "Not inlinable"));
+      }
       return false;
     }
 
@@ -492,6 +523,11 @@
         FLAG_deoptimization_counter_threshold) {
       function.set_is_inlinable(false);
       TRACE_INLINING(OS::Print("     Bailout: deoptimization threshold\n"));
+      if (FLAG_print_inlining_tree) {
+        inlined_info_.Add(InlinedInfo(
+            &call_data->caller, &function, inlining_depth_, call_data->call,
+            "Deoptimization threshold exceeded"));
+      }
       return false;
     }
 
@@ -508,6 +544,11 @@
                                function.optimized_instruction_count(),
                                function.optimized_call_site_count(),
                                constant_arguments));
+      if (FLAG_print_inlining_tree) {
+        inlined_info_.Add(InlinedInfo(
+            &call_data->caller, &function, inlining_depth_, call_data->call,
+            "Early heuristic"));
+      }
       return false;
     }
 
@@ -634,10 +675,10 @@
       for (intptr_t i = 0; i < param_stubs->length(); ++i) {
         if ((*param_stubs)[i]->IsConstant()) ++constants_count;
       }
-      GraphInfoCollector info;
-      info.Collect(*callee_graph);
-      const intptr_t size = info.instruction_count();
-      const intptr_t call_site_count = info.call_site_count();
+
+      FlowGraphInliner::CollectGraphInfo(callee_graph);
+      const intptr_t size = function.optimized_instruction_count();
+      const intptr_t call_site_count = function.optimized_call_site_count();
 
       function.set_optimized_instruction_count(size);
       function.set_optimized_call_site_count(call_site_count);
@@ -658,10 +699,17 @@
                                  size,
                                  call_site_count,
                                  constants_count));
+        if (FLAG_print_inlining_tree) {
+          inlined_info_.Add(InlinedInfo(
+              &call_data->caller, &function, inlining_depth_, call_data->call,
+              "Heuristic fail"));
+        }
         return false;
       }
 
-      collected_call_sites_->FindCallSites(callee_graph, inlining_depth_);
+      collected_call_sites_->FindCallSites(callee_graph,
+                                           inlining_depth_,
+                                           &inlined_info_);
 
       // Add the function to the cache.
       if (!in_cache) {
@@ -688,9 +736,9 @@
       // disconnected from its function during the rest of compilation.
       Code::ZoneHandle(unoptimized_code.raw());
       TRACE_INLINING(OS::Print("     Success\n"));
-      if (FLAG_print_inline_tree) {
+      if (FLAG_print_inlining_tree) {
         inlined_info_.Add(
-            InlinedInfo(&call_data->caller_, &function, inlining_depth_, call));
+            InlinedInfo(&call_data->caller, &function, inlining_depth_, call));
       }
       return true;
     } else {
@@ -704,16 +752,24 @@
   }
 
   void PrintInlinedInfo(const Function& top) {
-    OS::Print("Inlining into: %s\n", top.ToFullyQualifiedCString());
-    PrintInlinedInfoFor(top, 1);
+    if (inlined_info_.length() > 0) {
+      OS::Print("Inlining into: '%s' growth: %f (%"Pd" -> %"Pd")\n",
+          top.ToFullyQualifiedCString(),
+          GrowthFactor(),
+          initial_size_,
+          inlined_size_);
+      PrintInlinedInfoFor(top, 1);
+    }
   }
 
  private:
   friend class PolymorphicInliner;
 
   void PrintInlinedInfoFor(const Function& caller, intptr_t depth) {
+    // Print those that were inlined.
     for (intptr_t i = 0; i < inlined_info_.length(); i++) {
       const InlinedInfo& info = inlined_info_[i];
+      if (info.bailout_reason != NULL) continue;
       if ((info.inlined_depth == depth) &&
           (info.caller->raw() == caller.raw())) {
         for (int t = 0; t < depth; t++) {
@@ -725,6 +781,21 @@
         PrintInlinedInfoFor(*info.inlined, depth + 1);
       }
     }
+    // Print those that were not inlined.
+    for (intptr_t i = 0; i < inlined_info_.length(); i++) {
+      const InlinedInfo& info = inlined_info_[i];
+      if (info.bailout_reason == NULL) continue;
+      if ((info.inlined_depth == depth) &&
+          (info.caller->raw() == caller.raw())) {
+        for (int t = 0; t < depth; t++) {
+          OS::Print("  ");
+        }
+        OS::Print("NO %" Pd " %s - %s\n",
+            info.call_instr->GetDeoptId(),
+            info.inlined->ToQualifiedCString(),
+            info.bailout_reason);
+      }
+    }
   }
 
   void InlineCall(InlinedCallData* call_data) {
@@ -843,6 +914,14 @@
             target.ToCString(),
             target.deoptimization_counter(),
             call_info[call_idx].ratio));
+        if (FLAG_print_inlining_tree) {
+          inlined_info_.Add(InlinedInfo(
+              call_info[call_idx].caller,
+              &call->function(),
+              inlining_depth_,
+              call,
+              "Too cold"));
+        }
         continue;
       }
       GrowableArray<Value*> arguments(call->ArgumentCount());
@@ -912,6 +991,14 @@
             target.ToCString(),
             target.deoptimization_counter(),
             call_info[call_idx].ratio));
+        if (FLAG_print_inlining_tree) {
+          inlined_info_.Add(InlinedInfo(
+              call_info[call_idx].caller,
+              &target,
+              inlining_depth_,
+              call,
+              "Too cold"));
+        }
         continue;
       }
       GrowableArray<Value*> arguments(call->ArgumentCount());
@@ -1021,7 +1108,7 @@
 
   FlowGraph* caller_graph_;
   bool inlined_;
-  intptr_t initial_size_;
+  const intptr_t initial_size_;
   intptr_t inlined_size_;
   intptr_t inlining_depth_;
   CallSites* collected_call_sites_;
@@ -1496,13 +1583,16 @@
 }
 
 
-void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph) {
-  GraphInfoCollector info;
-  info.Collect(*flow_graph);
+void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) {
   const Function& function = flow_graph->parsed_function().function();
-  function.set_optimized_instruction_count(
-      ClampUint16(info.instruction_count()));
-  function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
+  if (force || (function.optimized_instruction_count() == 0)) {
+    GraphInfoCollector info;
+    info.Collect(*flow_graph);
+
+    function.set_optimized_instruction_count(
+        ClampUint16(info.instruction_count()));
+    function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
+  }
 }
 
 
@@ -1541,7 +1631,7 @@
 
   CallSiteInliner inliner(flow_graph_);
   inliner.InlineCalls();
-  if (FLAG_print_inline_tree) {
+  if (FLAG_print_inlining_tree) {
     inliner.PrintInlinedInfo(top);
   }
 
diff --git a/runtime/vm/flow_graph_inliner.h b/runtime/vm/flow_graph_inliner.h
index e408d92..42c4fcf 100644
--- a/runtime/vm/flow_graph_inliner.h
+++ b/runtime/vm/flow_graph_inliner.h
@@ -21,7 +21,8 @@
   // The flow graph is destructively updated upon inlining.
   void Inline();
 
-  static void CollectGraphInfo(FlowGraph* flow_graph);
+  // Compute graph info if it was not already computed or if 'force' is true.
+  static void CollectGraphInfo(FlowGraph* flow_graph, bool force = false);
 
   static bool AlwaysInline(const Function& function);
 
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index a349017..db7cee1 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -132,7 +132,7 @@
 }
 
 
-static void PrintICData(BufferFormatter* f, const ICData& ic_data) {
+static void PrintICDataHelper(BufferFormatter* f, const ICData& ic_data) {
   f->Print(" IC[%" Pd ": ", ic_data.NumberOfChecks());
   Function& target = Function::Handle();
   for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
@@ -159,6 +159,14 @@
 }
 
 
+void FlowGraphPrinter::PrintICData(const ICData& ic_data) {
+  char buffer[1024];
+  BufferFormatter f(buffer, sizeof(buffer));
+  PrintICDataHelper(&f, ic_data);
+  OS::Print("%s\n", buffer);
+}
+
+
 static void PrintUse(BufferFormatter* f, const Definition& definition) {
   if (definition.is_used()) {
     if (definition.HasSSATemp()) {
@@ -354,7 +362,7 @@
     PushArgumentAt(i)->value()->PrintTo(f);
   }
   if (HasICData()) {
-    PrintICData(f, *ic_data());
+    PrintICDataHelper(f, *ic_data());
   }
 }
 
@@ -365,7 +373,7 @@
     f->Print(", ");
     PushArgumentAt(i)->value()->PrintTo(f);
   }
-  PrintICData(f, ic_data());
+  PrintICDataHelper(f, ic_data());
 }
 
 
@@ -852,7 +860,7 @@
 
 void CheckClassInstr::PrintOperandsTo(BufferFormatter* f) const {
   value()->PrintTo(f);
-  PrintICData(f, unary_checks());
+  PrintICDataHelper(f, unary_checks());
   if (IsNullCheck()) {
     f->Print(" nullcheck");
   }
diff --git a/runtime/vm/il_printer.h b/runtime/vm/il_printer.h
index 77a642f..e61f65b 100644
--- a/runtime/vm/il_printer.h
+++ b/runtime/vm/il_printer.h
@@ -57,6 +57,9 @@
 
   static void PrintGraph(const char* phase, FlowGraph* flow_graph);
 
+  // Debugging helper function.
+  static void PrintICData(const ICData& ic_data);
+
  private:
   const Function& function_;
   const GrowableArray<BlockEntryInstr*>& block_order_;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 7e24716..7b4d385 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2150,7 +2150,7 @@
 }
 
 
-bool PolymorphicInstanceCallInstr::HasRecognizedTarget() const {
+bool PolymorphicInstanceCallInstr::HasSingleRecognizedTarget() const {
   return ic_data().HasOneTarget() &&
       (MethodRecognizer::RecognizeKind(
           Function::Handle(ic_data().GetTargetAt(0))) !=
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index ea370fe..1177d69 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -2974,7 +2974,7 @@
     return instance_call()->PushArgumentAt(index);
   }
 
-  bool HasRecognizedTarget() const;
+  bool HasSingleRecognizedTarget() const;
 
   virtual intptr_t CallCount() const { return ic_data().AggregateCount(); }
 
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 1157c78..51a4689 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -3187,6 +3187,9 @@
   }
 
   visitLiteralList(LiteralList node) {
+    bool oldSendIsMemberAccess = sendIsMemberAccess;
+    sendIsMemberAccess = false;
+
     NodeList arguments = node.typeArguments;
     DartType typeArgument;
     if (arguments != null) {
@@ -3221,6 +3224,8 @@
     if (node.isConst()) {
       analyzeConstant(node);
     }
+
+    sendIsMemberAccess = false;
   }
 
   visitConditional(Conditional node) {
@@ -3401,6 +3406,9 @@
   }
 
   visitLiteralMap(LiteralMap node) {
+    bool oldSendIsMemberAccess = sendIsMemberAccess;
+    sendIsMemberAccess = false;
+
     NodeList arguments = node.typeArguments;
     DartType keyTypeArgument;
     DartType valueTypeArgument;
@@ -3445,6 +3453,8 @@
     if (node.isConst()) {
       analyzeConstant(node);
     }
+
+    sendIsMemberAccess = false;
   }
 
   visitLiteralMapEntry(LiteralMapEntry node) {
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index d50e068..b054a77 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -256,8 +256,10 @@
   isHidden(part) => part.startsWith(".") && part != "." && part != "..";
 
   if (!includeHidden) {
-    entities = entities.where(
-        (entity) => !path.split(entity.path).any(isHidden));
+    entities = entities.where((entity) {
+      assert(entity.path.startsWith(dir));
+      return !path.split(entity.path.substring(dir.length + 1)).any(isHidden);
+    });
   }
 
   return entities.map((entity) => entity.path).toList();
diff --git a/sdk/lib/_internal/pub/test/io_test.dart b/sdk/lib/_internal/pub/test/io_test.dart
index a3d7b0e..cc5d2c4 100644
--- a/sdk/lib/_internal/pub/test/io_test.dart
+++ b/sdk/lib/_internal/pub/test/io_test.dart
@@ -50,6 +50,22 @@
         ]));
       }), completes);
     });
+
+    test("doesn't ignore hidden files above the directory being listed", () {
+      expect(withTempDir((temp) {
+        var dir = path.join(temp, '.foo', 'bar');
+        ensureDir(dir);
+        writeTextFile(path.join(dir, 'file1.txt'), '');
+        writeTextFile(path.join(dir, 'file2.txt'), '');
+        writeTextFile(path.join(dir, 'file3.txt'), '');
+
+        expect(listDir(dir, recursive: true), unorderedEquals([
+          path.join(dir, 'file1.txt'),
+          path.join(dir, 'file2.txt'),
+          path.join(dir, 'file3.txt')
+        ]));
+      }), completes);
+    });
   });
 
   group('canonicalize', () {
diff --git a/tests/language/first_class_types_literals_test.dart b/tests/language/first_class_types_literals_test.dart
index 8ba570a..422628a 100644
--- a/tests/language/first_class_types_literals_test.dart
+++ b/tests/language/first_class_types_literals_test.dart
@@ -15,6 +15,17 @@
 }
 
 main() {
+  void foo(a) {}
+
+  // Test that literals can be used in different contexts.
+  [int];
+  ([int]);
+  foo([int]);
+  [int].length;
+  ({1: int});
+  foo({1: int});
+  ({1: int}).keys;
+
   // Test type literals.
   Expect.equals(int, int);
   Expect.notEquals(int, num);
diff --git a/tools/VERSION b/tools/VERSION
index b013c08..251158c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 3
 PATCH 0
 PRERELEASE 7
-PRERELEASE_PATCH 2
+PRERELEASE_PATCH 3