Version 1.2.0-dev.5.6

svn merge -c 32629 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32685 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32692 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 32702 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@32712 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index b1de78e..47ea3a1b 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -541,10 +541,13 @@
 
     // For each deferred import we find out which outputUnits to load.
     for (Import import in _allDeferredImports.keys) {
+      if (import == _fakeMainImport) continue;
       hunksToLoad[importDeferName(import)] = new Set<OutputUnit>();
       for (OutputUnit outputUnit in allOutputUnits) {
         if (outputUnit == mainOutputUnit) continue;
-        hunksToLoad[importDeferName(import)].add(outputUnit);
+        if (outputUnit.imports.contains(import)) {
+          hunksToLoad[importDeferName(import)].add(outputUnit);
+        }
       }
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 444f6d0..3d58931 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -142,8 +142,13 @@
   Map<ClassElement, ClassElement> implementationClasses;
 
   Element getNativeInterceptorMethod;
+  bool needToInitializeIsolateAffinityTag = false;
   bool needToInitializeDispatchProperty = false;
 
+  /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been
+  /// loaded.
+  FunctionElement getIsolateAffinityTagMarker;
+
   final Namer namer;
 
   /**
@@ -801,6 +806,7 @@
     TreeElements elements = compiler.globalDependencies;
     enqueue(enqueuer, getNativeInterceptorMethod, elements);
     enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, elements);
+    needToInitializeIsolateAffinityTag = true;
     needToInitializeDispatchProperty = true;
   }
 
@@ -1552,6 +1558,8 @@
       mustPreserveNames = true;
     } else if (element == preserveMetadataMarker) {
       mustRetainMetadata = true;
+    } else if (element == getIsolateAffinityTagMarker) {
+      needToInitializeIsolateAffinityTag = true;
     }
     customElementsAnalysis.registerStaticUse(element, enqueuer);
   }
@@ -1612,6 +1620,9 @@
     } else if (uri == Uri.parse('dart:_js_names')) {
       preserveNamesMarker =
           library.find('preserveNames');
+    } else if (uri == Uri.parse('dart:_js_helper')) {
+      getIsolateAffinityTagMarker =
+          library.find('getIsolateAffinityTag');
     }
     return new Future.value();
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index a9f6407..33804f6 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -739,6 +739,8 @@
       return 'String';
     } else if (cls == backend.jsArrayClass) {
       return 'List';
+    } else if (cls == backend.jsNullClass) {
+      return 'Null';
     } else {
       return null;
     }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index 2f81f2d..531d1e6 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -972,20 +972,51 @@
     return "${namer.isolateAccess(isolateMain)}($mainAccess)";
   }
 
-  jsAst.Expression generateDispatchPropertyInitialization() {
+  /**
+   * Emits code that sets `init.isolateTag` to a unique string.
+   */
+  jsAst.Expression generateIsolateAffinityTagInitialization() {
     return js('!#', js.fun([], [
-        js('var objectProto = Object.prototype'),
+
+        // On V8, the 'intern' function converts a string to a symbol, which
+        // makes property access much faster.
+        new jsAst.FunctionDeclaration(new jsAst.VariableDeclaration('intern'),
+            js.fun(['s'], [
+                js('var o = {}'),
+                js('o[s] = 1'),
+                js.return_(js('Object.keys(convertToFastObject(o))[0]'))])),
+
+
+        js('init.getIsolateTag = #',
+            js.fun(['name'],
+                js.return_('intern("___dart_" + name + init.isolateTag)'))),
+
+        // To ensure that different programs loaded into the same context (page)
+        // use distinct dispatch properies, we place an object on `Object` to
+        // contain the names already in use.
+        js('var tableProperty = "___dart_isolate_tags_"'),
+        js('var usedProperties = Object[tableProperty] ||'
+            '(Object[tableProperty] = Object.create(null))'),
+
+        js('var rootProperty = "_${generateIsolateTagRoot()}"'),
         js.for_('var i = 0', null, 'i++', [
-            js('var property = "${generateDispatchPropertyName(0)}"'),
-            js.if_('i > 0', js('property = rootProperty + "_" + i')),
-            js.if_('!(property in  objectProto)',
-                   js.return_(
-                       js('init.dispatchPropertyName = property')))])])());
+            js('property = intern(rootProperty + "_" + i + "_")'),
+            js.if_('!(property in usedProperties)', [
+                js('usedProperties[property] = 1'),
+                js('init.isolateTag = property'),
+                new jsAst.Break(null)])])])
+        ());
+
   }
 
-  String generateDispatchPropertyName(int seed) {
+  jsAst.Expression generateDispatchPropertyNameInitialization() {
+    return js(
+        'init.dispatchPropertyName = init.getIsolateTag("dispatch_record")');
+  }
+
+  String generateIsolateTagRoot() {
     // TODO(sra): MD5 of contributing source code or URIs?
-    return '___dart_dispatch_record_ZxYxX_${seed}_';
+    return 'ZxYxX';
   }
 
   emitMain(CodeBuffer buffer) {
@@ -999,12 +1030,21 @@
     } else {
       mainCall = '${namer.isolateAccess(main)}()';
     }
-    if (backend.needToInitializeDispatchProperty) {
+
+    if (backend.needToInitializeIsolateAffinityTag) {
       buffer.write(
-          jsAst.prettyPrint(generateDispatchPropertyInitialization(),
+          jsAst.prettyPrint(generateIsolateAffinityTagInitialization(),
                             compiler));
       buffer.write(N);
     }
+    if (backend.needToInitializeDispatchProperty) {
+      assert(backend.needToInitializeIsolateAffinityTag);
+      buffer.write(
+          jsAst.prettyPrint(generateDispatchPropertyNameInitialization(),
+              compiler));
+      buffer.write(N);
+    }
+
     addComment('BEGIN invoke [main].', buffer);
     // This code finds the currently executing script by listening to the
     // onload event of all script tags and getting the first script which
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 4ab41ca..f97438c 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -803,7 +803,7 @@
       element.origin.ensureResolved(compiler);
       // Ensure that the type is computed.
       element.computeType(compiler);
-      // Copy class hiearchy from origin.
+      // Copy class hierarchy from origin.
       element.supertype = element.origin.supertype;
       element.interfaces = element.origin.interfaces;
       element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 92b23ad..cef540b 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -978,6 +978,7 @@
     if (JS('bool', '# == "num"', className)) return const JSNumber();
     if (JS('bool', '# == "bool"', className)) return const JSBool();
     if (JS('bool', '# == "List"', className)) return const JSArray();
+    if (JS('bool', '# == "Null"', className)) return const JSNull();
     return JS('var', 'init.allClasses[#]', className);
   }
 
@@ -3055,3 +3056,15 @@
   int int32b = JS("int", "(Math.random() * 0x100000000) >>> 0");
   return int32a + int32b * 0x100000000;
 }
+
+/**
+ * Returns a property name for placing data on JavaScript objects shared between
+ * DOM isolates.  This happens when multiple programs are loaded in the same
+ * JavaScript context (i.e. page).  The name is based on [name] but with an
+ * additional part that is unique for each isolate.
+ *
+ * The form of the name is '___dart_$name_$id'.
+ */
+String getIsolateAffinityTag(String name) {
+  return JS('String', 'init.getIsolateTag(#)', name);
+}
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 6b58b6f..0154824 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -878,10 +878,11 @@
   /// reflective information to know how to to invoke a specific member.
   get _classInvocationCache {
     String cacheName = Primitives.mirrorInvokeCacheName;
-    var cache = JS('', r'#.constructor[#]', reflectee, cacheName);
+    var cacheHolder = (reflectee == null) ? getInterceptor(null) : reflectee;
+    var cache = JS('', r'#.constructor[#]', cacheHolder, cacheName);
     if (cache == null) {
       cache = JsCache.allocate();
-      JS('void', r'#.constructor[#] = #', reflectee, cacheName, cache);
+      JS('void', r'#.constructor[#] = #', cacheHolder, cacheName, cache);
     }
     return cache;
   }
@@ -1070,7 +1071,7 @@
     // interceptor between multiple different instances of [InstanceMirror].
     var interceptor = getInterceptor(object);
     if (!useEval) return _newInterceptGetterNoEvalFn(name, interceptor);
-    String className = JS('String', '#.constructor.name', object);
+    String className = JS('String', '#.constructor.name', interceptor);
     var body = "(function $className\$$name(o){return i.$name(o)})";
     return JS('', '(function(b,i){return eval(b)})(#,#)', body, interceptor);
   }
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 576cb234..39b6c2a 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -94,7 +94,8 @@
 
 import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS;
 import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject;
-import 'dart:_js_helper' show Primitives, convertDartClosureToJS;
+import 'dart:_js_helper' show Primitives, convertDartClosureToJS,
+    getIsolateAffinityTag;
 
 final JsObject context = _wrapToDart(Primitives.computeGlobalThis());
 
@@ -451,8 +452,10 @@
 }
 
 // property added to a Dart object referencing its JS-side DartObject proxy
-const _DART_OBJECT_PROPERTY_NAME = r'_$dart_dartObject';
-const _DART_CLOSURE_PROPERTY_NAME = r'_$dart_dartClosure';
+final String _DART_OBJECT_PROPERTY_NAME =
+    getIsolateAffinityTag(r'_$dart_dartObject');
+final String _DART_CLOSURE_PROPERTY_NAME =
+    getIsolateAffinityTag(r'_$dart_dartClosure');
 
 // property added to a JS object referencing its Dart-side JsObject proxy
 const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject';
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index dc3c7ae..20a663c 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -65,6 +65,26 @@
     // InputElement is native, so it should not appear on a classList
     Expect.isFalse(outputClassLists[outputUnitForElement(inputElement)]
         .contains(inputElement));
+
+    var hunksToLoad = compiler.deferredLoadTask.hunksToLoad;
+    var hunksLib1 = new Set.from(hunksToLoad["lib1"].map((o) => o.name));
+    var hunksLib2 = new Set.from(hunksToLoad["lib2"].map((o) => o.name));
+    var hunksLib4_1 = new Set.from(hunksToLoad["lib4_1"].map((o) => o.name));
+    var hunksLib4_2 =  new Set.from(hunksToLoad["lib4_2"].map((o) => o.name));
+    Expect.equals(hunksLib1.length, 2);
+    Expect.isTrue(hunksLib1.contains("lib1"));
+    Expect.isTrue(hunksLib1.contains("lib1_lib2") ||
+                  hunksLib1.contains("lib2_lib1"));
+    Expect.isTrue(hunksLib2.contains("lib2"));
+    Expect.equals(hunksLib2.length, 2);
+    Expect.isTrue(hunksLib2.contains("lib1_lib2") ||
+                  hunksLib1.contains("lib2_lib1"));
+    Expect.isTrue(hunksLib4_1.contains("lib4_1"));
+    Expect.equals(hunksLib4_1.length, 1);
+    Expect.isTrue(hunksLib4_2.contains("lib4_2"));
+    Expect.equals(hunksLib4_2.length, 1);
+    Expect.equals(hunksToLoad["main"], null);
+
   }));
 }
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 662d9a9..38b41b7 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -146,8 +146,6 @@
 bit_operations_test: RuntimeError, OK # Issue 1533
 expect_test: RuntimeError, OK # Issue 13080
 
-null_test/none: RuntimeError  # Issue 12482
-
 [ ($compiler == dart2js || $compiler == dart2dart) && $checked ]
 cyclic_typedef_test/07: Crash # Issue 15237
 
diff --git a/tests/language/null2_test.dart b/tests/language/null2_test.dart
new file mode 100644
index 0000000..16d3a83
--- /dev/null
+++ b/tests/language/null2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// 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.
+// Second dart test program.
+
+import "package:expect/expect.dart";
+
+// Magic incantation to avoid the compiler recognizing the constant values
+// at compile time. If the result is computed at compile time, the dynamic code
+// will not be tested.
+confuse(x) {
+  try {
+    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
+    throw [x];
+  } on dynamic catch (e) { return e[0]; }
+  return 42;
+}
+
+main() {
+  Expect.equals("Null", null.runtimeType.toString());
+  Expect.equals("Null", confuse(null).runtimeType.toString());
+}
diff --git a/tests/language/null_test.dart b/tests/language/null_test.dart
index c499c50..83ffd7b 100644
--- a/tests/language/null_test.dart
+++ b/tests/language/null_test.dart
@@ -37,7 +37,10 @@
 // at compile time. If the result is computed at compile time, the dynamic code
 // will not be tested.
 confuse(x) {
-  try { throw [x]; } on dynamic catch (e) { return e[0]; }
+  try {
+    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
+    throw [x];
+  } on dynamic catch (e) { return e[0]; }
   return 42;
 }
 
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index fa7539b..bfa79c3 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -78,7 +78,6 @@
 mirrors/mirrors_test: RuntimeError # TODO(ahe): I'm working on fixing this.
 mirrors/mixin_test: RuntimeError # Issue 12464
 mirrors/mixin_application_test/none: RuntimeError # Issue 12464
-mirrors/null_test : RuntimeError # Issue 12129
 mirrors/parameter_test/none: RuntimeError # Issue 6490
 mirrors/parameter_metadata_test: RuntimeError # Issue 10905
 mirrors/private_symbol_test: CompileTimeError # Issue 13597
@@ -108,6 +107,7 @@
 typed_data/setRange_3_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 typed_data/setRange_4_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 mirrors/to_string_test: Fail # Safari bug TODO(ahe): Add bug number if able to submit bug.
+mirrors/null_test: Fail # http://dartbug.com/16831
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 typed_data/setRange_2_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
@@ -175,7 +175,8 @@
                                          # implement timer (currently only in d8)
 
 [ $compiler == dart2js && $minified ]
-mirrors/intercepted_superclass_test: RuntimeError # Issue 16389
+mirrors/intercepted_superclass_test: RuntimeError # Issue 16804
+mirrors/null_test/00: RuntimeError # Issue 16804. Please remove the multi-test comments when this test starts succeeding.
 
 [ $compiler == dart2dart ]
 mirrors/*: Skip # http://dartbug.com/11511
diff --git a/tests/lib/mirrors/null2_test.dart b/tests/lib/mirrors/null2_test.dart
new file mode 100644
index 0000000..4c5590d
--- /dev/null
+++ b/tests/lib/mirrors/null2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// 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.
+
+library test.null_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() {
+  InstanceMirror nullMirror = reflect(null);
+  for (int i = 0; i < 10; i++) {
+    Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int);
+  }
+}
diff --git a/tests/lib/mirrors/null_test.dart b/tests/lib/mirrors/null_test.dart
index 72f5e23..d0069d2 100644
--- a/tests/lib/mirrors/null_test.dart
+++ b/tests/lib/mirrors/null_test.dart
@@ -28,8 +28,8 @@
   ClassMirror NullMirror = nullMirror.type;
   Expect.equals(reflectClass(Null), NullMirror);
   Expect.equals(#Null, NullMirror.simpleName);
-  Expect.equals(#Object, NullMirror.superclass.simpleName);
-  Expect.equals(null, NullMirror.superclass.superclass);
+  Expect.equals(#Object, NullMirror.superclass.simpleName);  /// 00: ok
+  Expect.equals(null, NullMirror.superclass.superclass);  /// 00: continued
   Expect.listEquals([], NullMirror.superinterfaces);
   Expect.equals(currentMirrorSystem().libraries[Uri.parse('dart:core')],
                 NullMirror.owner);
diff --git a/tools/VERSION b/tools/VERSION
index 0ff063f..a101173 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 2
 PATCH 0
 PRERELEASE 5
-PRERELEASE_PATCH 7
+PRERELEASE_PATCH 8