| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /// Enables debugging of fast/slow objects using V8-specific primitives. |
| 7 const DEBUG_FAST_OBJECTS = false; | 8 const DEBUG_FAST_OBJECTS = false; |
| 8 | 9 |
| 9 /** | 10 /** |
| 10 * A function element that represents a closure call. The signature is copied | 11 * A function element that represents a closure call. The signature is copied |
| 11 * from the given element. | 12 * from the given element. |
| 12 */ | 13 */ |
| 13 class ClosureInvocationElement extends FunctionElementX { | 14 class ClosureInvocationElement extends FunctionElementX { |
| 14 ClosureInvocationElement(SourceString name, | 15 ClosureInvocationElement(SourceString name, |
| 15 FunctionElement other) | 16 FunctionElement other) |
| 16 : super.from(name, other, other.enclosingElement), | 17 : super.from(name, other, other.enclosingElement), |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 | 697 |
| 697 List<jsAst.Node> statements = [ | 698 List<jsAst.Node> statements = [ |
| 698 js('var pendingClasses = {}'), | 699 js('var pendingClasses = {}'), |
| 699 js.if_('!init.allClasses', js('init.allClasses = {}')), | 700 js.if_('!init.allClasses', js('init.allClasses = {}')), |
| 700 js('var allClasses = init.allClasses'), | 701 js('var allClasses = init.allClasses'), |
| 701 | 702 |
| 702 js('var hasOwnProperty = Object.prototype.hasOwnProperty'), | 703 js('var hasOwnProperty = Object.prototype.hasOwnProperty'), |
| 703 | 704 |
| 704 optional( | 705 optional( |
| 705 DEBUG_FAST_OBJECTS, | 706 DEBUG_FAST_OBJECTS, |
| 706 js(r'print("Number of classes: " + Object.getOwnPropertyNames($$).leng
th)')), | 707 js(r'print("Number of classes: "' |
| 708 ' + Object.getOwnPropertyNames($$).length)')), |
| 707 | 709 |
| 708 js.forIn('cls', 'collectedClasses', [ | 710 js.forIn('cls', 'collectedClasses', [ |
| 709 js.if_('hasOwnProperty.call(collectedClasses, cls)', [ | 711 js.if_('hasOwnProperty.call(collectedClasses, cls)', [ |
| 710 js('var desc = collectedClasses[cls]'), | 712 js('var desc = collectedClasses[cls]'), |
| 711 js('var globalObject = isolateProperties'), | 713 js('var globalObject = isolateProperties'), |
| 712 js.if_('desc instanceof Array', [ | 714 js.if_('desc instanceof Array', [ |
| 713 js('globalObject = desc[0] || isolateProperties'), | 715 js('globalObject = desc[0] || isolateProperties'), |
| 714 js('desc = desc[1]') | 716 js('desc = desc[1]') |
| 715 ]), | 717 ]), |
| 716 | 718 |
| (...skipping 3006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3723 buffer.write(metadata); | 3725 buffer.write(metadata); |
| 3724 } | 3726 } |
| 3725 } else { | 3727 } else { |
| 3726 throw 'Unexpected value in metadata: ${Error.safeToString(metadata)}'; | 3728 throw 'Unexpected value in metadata: ${Error.safeToString(metadata)}'; |
| 3727 } | 3729 } |
| 3728 buffer.write(',$n'); | 3730 buffer.write(',$n'); |
| 3729 } | 3731 } |
| 3730 buffer.write('];$n'); | 3732 buffer.write('];$n'); |
| 3731 } | 3733 } |
| 3732 | 3734 |
| 3733 void emitInstancify() { | 3735 void emitConvertToFastObjectFunction() { |
| 3734 mainBuffer.add(r''' | 3736 mainBuffer.add(r''' |
| 3735 function instancify(properties) { | 3737 function convertToFastObject(properties) { |
| 3736 function makeConstructor() { | 3738 function makeConstructor() { |
| 3737 var str = "{\n"; | 3739 var str = "{\n"; |
| 3738 var hasOwnProperty = Object.prototype.hasOwnProperty; | 3740 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 3739 for (var property in properties) { | 3741 for (var property in properties) { |
| 3740 if (hasOwnProperty.call(properties, property)) { | 3742 if (hasOwnProperty.call(properties, property)) { |
| 3741 str += "this." + property + "= properties." + property + ";\n"; | 3743 str += "this." + property + "= properties." + property + ";\n"; |
| 3742 } | 3744 } |
| 3743 } | 3745 } |
| 3744 str += "}\n"; | 3746 str += "}\n"; |
| 3745 return new Function("properties", str); | 3747 return new Function("properties", str); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3759 computeNeededClasses(); | 3761 computeNeededClasses(); |
| 3760 | 3762 |
| 3761 mainBuffer.add(buildGeneratedBy()); | 3763 mainBuffer.add(buildGeneratedBy()); |
| 3762 addComment(HOOKS_API_USAGE, mainBuffer); | 3764 addComment(HOOKS_API_USAGE, mainBuffer); |
| 3763 | 3765 |
| 3764 if (!areAnyElementsDeferred) { | 3766 if (!areAnyElementsDeferred) { |
| 3765 mainBuffer.add('(function(${namer.CURRENT_ISOLATE})$_{$n'); | 3767 mainBuffer.add('(function(${namer.CURRENT_ISOLATE})$_{$n'); |
| 3766 } | 3768 } |
| 3767 | 3769 |
| 3768 for (String globalObject in Namer.reservedGlobalObjectNames) { | 3770 for (String globalObject in Namer.reservedGlobalObjectNames) { |
| 3771 // The global objects start as so-called "slow objects". For V8, this |
| 3772 // means that it won't try to make map transitions as we add properties |
| 3773 // to these objects. Later on, we attempt to turn these objects into |
| 3774 // fast objects by calling "convertToFastObject" (see |
| 3775 // [emitConvertToFastObjectFunction]). |
| 3769 mainBuffer | 3776 mainBuffer |
| 3770 ..write('var ${globalObject}$_=$_{}$N') | 3777 ..write('var ${globalObject}$_=$_{}$N') |
| 3771 ..write('delete ${globalObject}.x$N'); | 3778 ..write('delete ${globalObject}.x$N'); |
| 3772 } | 3779 } |
| 3773 | 3780 |
| 3774 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); | 3781 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); |
| 3775 mainBuffer.add('init()$N$n'); | 3782 mainBuffer.add('init()$N$n'); |
| 3776 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. | 3783 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. |
| 3777 isolateProperties = namer.CURRENT_ISOLATE; | 3784 isolateProperties = namer.CURRENT_ISOLATE; |
| 3778 mainBuffer.add( | 3785 mainBuffer.add( |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3987 | 3994 |
| 3988 isolateProperties = isolatePropertiesName; | 3995 isolateProperties = isolatePropertiesName; |
| 3989 // The following code should not use the short-hand for the | 3996 // The following code should not use the short-hand for the |
| 3990 // initialStatics. | 3997 // initialStatics. |
| 3991 mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N'); | 3998 mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N'); |
| 3992 | 3999 |
| 3993 emitFinishIsolateConstructorInvocation(mainBuffer); | 4000 emitFinishIsolateConstructorInvocation(mainBuffer); |
| 3994 mainBuffer.add( | 4001 mainBuffer.add( |
| 3995 '${namer.CURRENT_ISOLATE}$_=${_}new ${namer.isolateName}()$N'); | 4002 '${namer.CURRENT_ISOLATE}$_=${_}new ${namer.isolateName}()$N'); |
| 3996 | 4003 |
| 3997 emitInstancify(); | 4004 emitConvertToFastObjectFunction(); |
| 3998 for (String globalObject in Namer.reservedGlobalObjectNames) { | 4005 for (String globalObject in Namer.reservedGlobalObjectNames) { |
| 3999 mainBuffer.add('$globalObject = instancify($globalObject)$N'); | 4006 mainBuffer.add('$globalObject = convertToFastObject($globalObject)$N'); |
| 4000 } | 4007 } |
| 4001 if (DEBUG_FAST_OBJECTS) { | 4008 if (DEBUG_FAST_OBJECTS) { |
| 4002 ClassElement primitives = | 4009 ClassElement primitives = |
| 4003 compiler.findHelper(const SourceString('Primitives')); | 4010 compiler.findHelper(const SourceString('Primitives')); |
| 4004 FunctionElement printHelper = | 4011 FunctionElement printHelper = |
| 4005 compiler.lookupElementIn( | 4012 compiler.lookupElementIn( |
| 4006 primitives, const SourceString('printString')); | 4013 primitives, const SourceString('printString')); |
| 4007 String printHelperName = namer.isolateAccess(printHelper); | 4014 String printHelperName = namer.isolateAccess(printHelper); |
| 4008 | 4015 |
| 4009 mainBuffer.add(''' | 4016 mainBuffer.add(''' |
| 4017 // The following only works on V8 when run with option "--allow-natives-syntax". |
| 4010 if (typeof $printHelperName === "function") { | 4018 if (typeof $printHelperName === "function") { |
| 4011 $printHelperName("Size of global helper object: " | 4019 $printHelperName("Size of global helper object: " |
| 4012 + String(Object.getOwnPropertyNames(H).length) | 4020 + String(Object.getOwnPropertyNames(H).length) |
| 4013 + ", fast properties " + %HasFastProperties(H)); | 4021 + ", fast properties " + %HasFastProperties(H)); |
| 4014 $printHelperName("Size of global platform object: " | 4022 $printHelperName("Size of global platform object: " |
| 4015 + String(Object.getOwnPropertyNames(P).length) | 4023 + String(Object.getOwnPropertyNames(P).length) |
| 4016 + ", fast properties " + %HasFastProperties(P)); | 4024 + ", fast properties " + %HasFastProperties(P)); |
| 4017 $printHelperName("Size of global dart:html object: " | 4025 $printHelperName("Size of global dart:html object: " |
| 4018 + String(Object.getOwnPropertyNames(W).length) | 4026 + String(Object.getOwnPropertyNames(W).length) |
| 4019 + ", fast properties " + %HasFastProperties(W)); | 4027 + ", fast properties " + %HasFastProperties(W)); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4294 | 4302 |
| 4295 const String HOOKS_API_USAGE = """ | 4303 const String HOOKS_API_USAGE = """ |
| 4296 // The code supports the following hooks: | 4304 // The code supports the following hooks: |
| 4297 // dartPrint(message) - if this function is defined it is called | 4305 // dartPrint(message) - if this function is defined it is called |
| 4298 // instead of the Dart [print] method. | 4306 // instead of the Dart [print] method. |
| 4299 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4307 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4300 // method will not be invoked directly. | 4308 // method will not be invoked directly. |
| 4301 // Instead, a closure that will invoke [main] is | 4309 // Instead, a closure that will invoke [main] is |
| 4302 // passed to [dartMainRunner]. | 4310 // passed to [dartMainRunner]. |
| 4303 """; | 4311 """; |
| OLD | NEW |