Skip to content

Commit a99bb14

Browse files
author
jossonsmith
committed
ClassLoader now can load *.js in multiple threads!
1 parent fd4ba65 commit a99bb14

File tree

2 files changed

+121
-17
lines changed

2 files changed

+121
-17
lines changed

sources/net.sf.j2s.java.core/src/java/lang/ClassLoader.js

Lines changed: 106 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,29 @@ ClazzLoader.clazzTreeRoot = new ClazzNode ();
101101
/*-# loadedScripts -> ls #-*/
102102
ClazzLoader.loadedScripts = new Object ();
103103

104+
/**
105+
* Multiple threads are used to speed up *.js loading.
106+
*/
107+
/* private */
108+
/*-# inLoadingThreads -> ilt #-*/
109+
ClazzLoader.inLoadingThreads = 0;
110+
111+
/**
112+
* Maximum of loading threads
113+
*/
114+
/* protected */
115+
ClazzLoader.maxLoadingThreads = 6;
116+
117+
/*
118+
* Opera has different loading order which will result in performance degrade!
119+
* So just return to single thread loading in Opera!
120+
*
121+
* FIXME: This different loading order also causes bugs in single thread!
122+
*/
123+
if (navigator.userAgent.toLowerCase ().indexOf ("opera") != -1) {
124+
ClazzLoader.maxLoadingThreads = 1;
125+
}
126+
104127
/**
105128
* Try to be compatiable with Clazz system.
106129
*/
@@ -584,9 +607,6 @@ ClazzLoader.xhrOnload = function (transport, file) {
584607
ClazzLoader.emptyOnRSC = function () {
585608
};
586609

587-
/* private */
588-
ClazzLoader.lastScriptPath = null;
589-
590610
/* protected */
591611
/*-# failedScripts -> fss #-*/
592612
ClazzLoader.failedScripts = new Object ();
@@ -614,7 +634,6 @@ ClazzLoader.loadScript = function (file) {
614634
ClazzLoader.tryToLoadNext (file);
615635
return ;
616636
}
617-
ClazzLoader.lastScriptPath = file;
618637
ClazzLoader.loadedScripts[file] = true;
619638

620639
if (ClazzLoader.isUsingXMLHttpRequest) {
@@ -641,6 +660,9 @@ ClazzLoader.loadScript = function (file) {
641660
if (ClazzLoader.isAsynchronousLoading) {
642661
transport.onreadystatechange = function () {
643662
if (transport.readyState == 4) {
663+
if (ClazzLoader.inLoadingThreads > 0) {
664+
ClazzLoader.inLoadingThreads--;
665+
}
644666
if (isActiveX) {
645667
transport.onreadystatechange = ClazzLoader.emptyOnRSC;
646668
// For IE, try to avoid stack overflow errors
@@ -660,6 +682,7 @@ ClazzLoader.loadScript = function (file) {
660682
}
661683
}
662684
};
685+
ClazzLoader.inLoadingThreads++;
663686
try {
664687
transport.send (null);
665688
} catch (e) {
@@ -698,6 +721,9 @@ ClazzLoader.loadScript = function (file) {
698721
* Opera will trigger onload event even there are no *.js existed
699722
*/
700723
script.onload = function () {
724+
if (ClazzLoader.inLoadingThreads > 0) {
725+
ClazzLoader.inLoadingThreads--;
726+
}
701727
this.onload = null;
702728
var path = arguments.callee.path;
703729
if (!ClazzLoader.isInnerLoaded
@@ -729,6 +755,9 @@ ClazzLoader.loadScript = function (file) {
729755
* For Firefox/Mozilla, unexisted *.js will result in errors.
730756
*/
731757
script.onerror = function () { // Firefox/Mozilla
758+
if (ClazzLoader.inLoadingThreads > 0) {
759+
ClazzLoader.inLoadingThreads--;
760+
}
732761
this.onerror = null;
733762
var path = arguments.callee.path;
734763
var fss = ClazzLoader.failedScripts;
@@ -784,6 +813,10 @@ ClazzLoader.loadScript = function (file) {
784813
// next time in "loading" state won't get waiting!
785814
ClazzLoader.failedScripts[path] = 0;
786815
ClazzLoader.loadedScripts[path] = false;
816+
// failed count down!
817+
if (ClazzLoader.inLoadingThreads > 0) {
818+
ClazzLoader.inLoadingThreads--;
819+
}
787820
// Take another try!
788821
ClazzLoader.loadScript (path);
789822
};
@@ -797,7 +830,7 @@ ClazzLoader.loadScript = function (file) {
797830
fhs[path] = window.setTimeout (fun, waitingTime);
798831
return;
799832
}
800-
if (fss[path] == 1) {
833+
if (fss[path] == 1) { // above function will be executed?!
801834
return;
802835
}
803836
}
@@ -807,6 +840,10 @@ ClazzLoader.loadScript = function (file) {
807840
}
808841
if ((local || state == "loaded") && !ClazzLoader.isInnerLoaded) {
809842
if (!local && (fss[path] == null || fss[path] == 0)) {
843+
// failed! count down
844+
if (ClazzLoader.inLoadingThreads > 0) {
845+
ClazzLoader.inLoadingThreads--;
846+
}
810847
// silently take another try for bad network
811848
fss[path] = 1;
812849
// log ("reloading ... " + path);
@@ -817,6 +854,9 @@ ClazzLoader.loadScript = function (file) {
817854
alert ("[Java2Script] Error in loading " + path + "!");
818855
}
819856
}
857+
if (ClazzLoader.inLoadingThreads > 0) {
858+
ClazzLoader.inLoadingThreads--;
859+
}
820860
ClazzLoader.scriptLoaded (path);
821861
// Unset onreadystatechange, leaks mem in IE
822862
this.onreadystatechange = null;
@@ -831,6 +871,8 @@ ClazzLoader.loadScript = function (file) {
831871
script.onreadystatechange.path = file;
832872
}
833873
ClazzLoader.isInnerLoaded = false;
874+
ClazzLoader.inLoadingThreads++;
875+
//alert("threads:"+ClazzLoader.inLoadingThreads);
834876
// Add script DOM element to document tree
835877
head.appendChild (script);
836878
ClazzLoader.scriptLoading (file);
@@ -873,6 +915,7 @@ ClazzLoader.isResourceExisted = function (id, path, base) {
873915
}
874916
return false;
875917
};
918+
876919
/**
877920
* After class is loaded, this method will be executed to check whether there
878921
* are classes in the dependency tree that need to be loaded.
@@ -904,7 +947,13 @@ ClazzLoader.tryToLoadNext = function (file) {
904947
} else {
905948
n = new ClazzNode ();
906949
n.name = nm;
907-
n.path = ClazzLoader.lastScriptPath;
950+
var pp = ClazzLoader.classpathMap["#" + nm];
951+
if (pp == null) {
952+
log (nm);
953+
error ("Java2Script implementation error! Please report this bug!");
954+
}
955+
//n.path = ClazzLoader.lastScriptPath;
956+
n.path = pp;
908957
//error ("..." + node.path + "//" + node.name);
909958
ClazzLoader.mappingPathNameNode (n.path, nm, n);
910959
n.status = ClazzNode.STATUS_CONTENT_LOADED;
@@ -941,14 +990,21 @@ ClazzLoader.tryToLoadNext = function (file) {
941990
var loadFurther = false;
942991
var n = ClazzLoader.findNextMustClass (ClazzLoader.clazzTreeRoot,
943992
ClazzNode.STATUS_KNOWN);
944-
//alert ("next..." + n) ;
993+
//alert (file + " next ..." + n) ;
945994
if (n != null) {
946995
//log ("next ..." + n.name);
947996
ClazzLoader.loadClassNode (n);
997+
while (ClazzLoader.inLoadingThreads < ClazzLoader.maxLoadingThreads) {
998+
var nn = ClazzLoader.findNextMustClass (ClazzLoader.clazzTreeRoot,
999+
ClazzNode.STATUS_KNOWN);
1000+
if (nn == null) break;
1001+
ClazzLoader.loadClassNode (nn); // will increase inLoadingThreads!
1002+
}
9481003
} else {
9491004
var cq = ClazzLoader.classQueue;
950-
if (cq.length != 0) {
951-
n = cq[0]; // popup class from the quue
1005+
if (cq.length != 0) {
1006+
/* queue must be loaded in order! */
1007+
n = cq[0]; // popup class from the queue
9521008
for (var i = 0; i < cq.length - 1; i++) {
9531009
cq[i] = cq[i + 1];
9541010
}
@@ -958,16 +1014,23 @@ ClazzLoader.tryToLoadNext = function (file) {
9581014
//alert ("load from queue");
9591015
ClazzLoader.loadScript (n.path);
9601016
} else { // Optionals
1017+
//log ("options");
9611018
n = ClazzLoader.findNextOptionalClass (ClazzNode.STATUS_KNOWN);
9621019
if (n != null) {
9631020
//log ("in optionals unknown..." + n.name);
9641021
ClazzLoader.loadClassNode (n);
1022+
while (ClazzLoader.inLoadingThreads < ClazzLoader.maxLoadingThreads) {
1023+
var nn = ClazzLoader.findNextOptionalClass (ClazzNode.STATUS_KNOWN);
1024+
//log ("in second loading " + nn);
1025+
if (nn == null) break;
1026+
ClazzLoader.loadClassNode (nn); // will increase inLoadingThreads!
1027+
}
9651028
} else {
9661029
loadFurther = true;
9671030
}
9681031
}
9691032
}
970-
if (loadFurther) {
1033+
if (loadFurther && ClazzLoader.inLoadingThreads == 0) {
9711034
//error ("no optionals?");
9721035
while ((n = ClazzLoader.findNextMustClass (ClazzLoader.clazzTreeRoot, ClazzNode.STATUS_CONTENT_LOADED)) != null) {
9731036
ClazzLoader.updateNode (n);
@@ -1235,7 +1298,9 @@ ClazzLoader.findNextMustClass = function (node, status) {
12351298
if (node.musts != null && node.musts.length != 0) {
12361299
for (var i = 0; i < node.musts.length; i++) {
12371300
var n = node.musts[i];
1238-
if (n.status == status) {
1301+
if (n.status == status && (status != ClazzNode.STATUS_KNOWN
1302+
|| ClazzLoader.loadedScripts[n.path] != true)
1303+
&& !ClazzLoader.isClassDefined (n.name)) {
12391304
return n;
12401305
} else {
12411306
var nn = ClazzLoader.findNextMustClass (n, status);
@@ -1245,7 +1310,9 @@ ClazzLoader.findNextMustClass = function (node, status) {
12451310
}
12461311
}
12471312
}
1248-
if (node.status == status) {
1313+
if (node.status == status && (status != ClazzNode.STATUS_KNOWN
1314+
|| ClazzLoader.loadedScripts[node.path] != true)
1315+
&& !ClazzLoader.isClassDefined (node.name)) {
12491316
return node;
12501317
}
12511318
}
@@ -1271,19 +1338,25 @@ ClazzLoader.findNodeNextOptionalClass = function (node, status) {
12711338
// search musts first
12721339
if (node.musts != null && node.musts.length != 0) {
12731340
var n = ClazzLoader.searchClassArray (node.musts, rnd, status);
1274-
if (n != null) {
1341+
if (n != null && (status != ClazzNode.STATUS_KNOWN
1342+
|| ClazzLoader.loadedScripts[n.path] != true)
1343+
&& !ClazzLoader.isClassDefined (n.name)) {
12751344
return n;
12761345
}
12771346
}
12781347
// search optionals second
12791348
if (node.optionals != null && node.optionals.length != 0) {
12801349
var n = ClazzLoader.searchClassArray (node.optionals, rnd, status);
1281-
if (n != null) {
1350+
if (n != null && (status != ClazzNode.STATUS_KNOWN
1351+
|| ClazzLoader.loadedScripts[n.path] != true)
1352+
&& !ClazzLoader.isClassDefined (n.name)) {
12821353
return n;
12831354
}
12841355
}
12851356
// search itself
1286-
if (node.status == status) {
1357+
if (node.status == status && (status != ClazzNode.STATUS_KNOWN
1358+
|| ClazzLoader.loadedScripts[node.path] != true)
1359+
&& !ClazzLoader.isClassDefined (node.name)) {
12871360
return node;
12881361
}
12891362
return null;
@@ -1293,7 +1366,9 @@ ClazzLoader.findNodeNextOptionalClass = function (node, status) {
12931366
ClazzLoader.searchClassArray = function (arr, rnd, status) {
12941367
for (var i = 0; i < arr.length; i++) {
12951368
var n = arr[i];
1296-
if (n.status == status) {
1369+
if (n.status == status && (status != ClazzNode.STATUS_KNOWN
1370+
|| ClazzLoader.loadedScripts[n.path] != true)
1371+
&& !ClazzLoader.isClassDefined (n.name)) {
12971372
return n;
12981373
} else {
12991374
if (n.random == rnd) {
@@ -1345,7 +1420,13 @@ ClazzLoader.load = function (musts, clazz, optionals, declaration) {
13451420
//*
13461421
//node = new ClazzNode ();
13471422
node.name = clazz;
1348-
node.path = ClazzLoader.lastScriptPath;
1423+
var pp = ClazzLoader.classpathMap["#" + clazz];
1424+
if (pp == null) {
1425+
log (clazz);
1426+
error ("Java2Script implementation error! Please report this bug!");
1427+
}
1428+
//node.path = ClazzLoader.lastScriptPath;
1429+
node.path = pp;
13491430
//error ("..." + node.path + "//" + node.name);
13501431
ClazzLoader.mappingPathNameNode (node.path, clazz, node);
13511432
node.status = ClazzNode.STATUS_KNOWN;
@@ -1498,6 +1579,12 @@ ClazzLoader.findClassUnderNode = function (clazzName, node) {
14981579
return null;
14991580
};
15001581

1582+
/**
1583+
* Map different class to the same path!
1584+
* @path *.js path
1585+
* @name class name
1586+
* @node ClazzNode object
1587+
*/
15011588
/* private */
15021589
/*-# mappingPathNameNode -> mpp #-*/
15031590
ClazzLoader.mappingPathNameNode = function (path, name, node) {
@@ -1539,8 +1626,10 @@ ClazzLoader.loadClassNode = function (node) {
15391626
ClazzLoader.mappingPathNameNode (path, name, node);
15401627
if (!ClazzLoader.loadedScripts[path]) {
15411628
ClazzLoader.loadScript (path);
1629+
return true;
15421630
}
15431631
}
1632+
return false;
15441633
};
15451634

15461635

sources/net.sf.j2s.java.core/src/java/package.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@
99
ClazzLoader.loadZJar (base + "error.z.js", "java.lang.Throwable");
1010
ClazzLoader.loadZJar (base + "core.z.js", ClazzLoader.runtimeKeyClass); //"java.lang.String"
1111

12+
ClazzLoader.jarClasspath (base + "core.z.js", [
13+
"net.sf.j2s.ajax.HttpRequest",
14+
"$.IXHRCallback",
15+
"$.XHRCallbackAdapter",
16+
"$.XHRCallbackSWTAdapter",
17+
"$.ARunnable",
18+
"$.AClass",
19+
"$.ASWTClass",
20+
21+
"$.SimpleSerializable",
22+
"$.SimpleRPCRunnable",
23+
"$.SimpleRPCRequest",
24+
"$.SimpleRPCSWTRequest"
25+
]);
26+
1227
ClazzLoader.jarClasspath (base + "util/AbstractList.js", [
1328
"java.util.AbstractList",
1429
"$.RandomAccessSubList",

0 commit comments

Comments
 (0)