34 import jdk.nashorn.internal.ir.Block; |
34 import jdk.nashorn.internal.ir.Block; |
35 import jdk.nashorn.internal.ir.FunctionNode; |
35 import jdk.nashorn.internal.ir.FunctionNode; |
36 import jdk.nashorn.internal.ir.LexicalContext; |
36 import jdk.nashorn.internal.ir.LexicalContext; |
37 import jdk.nashorn.internal.ir.LiteralNode; |
37 import jdk.nashorn.internal.ir.LiteralNode; |
38 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; |
38 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; |
39 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; |
|
40 import jdk.nashorn.internal.ir.Node; |
39 import jdk.nashorn.internal.ir.Node; |
|
40 import jdk.nashorn.internal.ir.ObjectNode; |
|
41 import jdk.nashorn.internal.ir.PropertyNode; |
41 import jdk.nashorn.internal.ir.SplitNode; |
42 import jdk.nashorn.internal.ir.SplitNode; |
|
43 import jdk.nashorn.internal.ir.Splittable; |
42 import jdk.nashorn.internal.ir.Statement; |
44 import jdk.nashorn.internal.ir.Statement; |
43 import jdk.nashorn.internal.ir.visitor.NodeVisitor; |
45 import jdk.nashorn.internal.ir.visitor.NodeVisitor; |
44 import jdk.nashorn.internal.runtime.Context; |
46 import jdk.nashorn.internal.runtime.Context; |
45 import jdk.nashorn.internal.runtime.logging.DebugLogger; |
47 import jdk.nashorn.internal.runtime.logging.DebugLogger; |
46 import jdk.nashorn.internal.runtime.logging.Loggable; |
48 import jdk.nashorn.internal.runtime.logging.Loggable; |
293 |
295 |
294 if (literal instanceof ArrayLiteralNode) { |
296 if (literal instanceof ArrayLiteralNode) { |
295 final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal; |
297 final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode) literal; |
296 final Node[] value = arrayLiteralNode.getValue(); |
298 final Node[] value = arrayLiteralNode.getValue(); |
297 final int[] postsets = arrayLiteralNode.getPostsets(); |
299 final int[] postsets = arrayLiteralNode.getPostsets(); |
298 final List<ArrayUnit> units = new ArrayList<>(); |
300 final List<Splittable.SplitRange> ranges = new ArrayList<>(); |
299 |
301 |
300 long totalWeight = 0; |
302 long totalWeight = 0; |
301 int lo = 0; |
303 int lo = 0; |
302 |
304 |
303 for (int i = 0; i < postsets.length; i++) { |
305 for (int i = 0; i < postsets.length; i++) { |
307 weight = WeighNodes.weigh(element); |
309 weight = WeighNodes.weigh(element); |
308 totalWeight += WeighNodes.AASTORE_WEIGHT + weight; |
310 totalWeight += WeighNodes.AASTORE_WEIGHT + weight; |
309 |
311 |
310 if (totalWeight >= SPLIT_THRESHOLD) { |
312 if (totalWeight >= SPLIT_THRESHOLD) { |
311 final CompileUnit unit = compiler.findUnit(totalWeight - weight); |
313 final CompileUnit unit = compiler.findUnit(totalWeight - weight); |
312 units.add(new ArrayUnit(unit, lo, i)); |
314 ranges.add(new Splittable.SplitRange(unit, lo, i)); |
313 lo = i; |
315 lo = i; |
314 totalWeight = weight; |
316 totalWeight = weight; |
315 } |
317 } |
316 } |
318 } |
317 |
319 |
318 if (lo != postsets.length) { |
320 if (lo != postsets.length) { |
319 final CompileUnit unit = compiler.findUnit(totalWeight); |
321 final CompileUnit unit = compiler.findUnit(totalWeight); |
320 units.add(new ArrayUnit(unit, lo, postsets.length)); |
322 ranges.add(new Splittable.SplitRange(unit, lo, postsets.length)); |
321 } |
323 } |
322 |
324 |
323 return arrayLiteralNode.setUnits(lc, units); |
325 return arrayLiteralNode.setSplitRanges(lc, ranges); |
324 } |
326 } |
325 |
327 |
326 return literal; |
328 return literal; |
|
329 } |
|
330 |
|
331 @Override |
|
332 public Node leaveObjectNode(final ObjectNode objectNode) { |
|
333 long weight = WeighNodes.weigh(objectNode); |
|
334 |
|
335 if (weight < SPLIT_THRESHOLD) { |
|
336 return objectNode; |
|
337 } |
|
338 |
|
339 final FunctionNode functionNode = lc.getCurrentFunction(); |
|
340 lc.setFlag(functionNode, FunctionNode.IS_SPLIT); |
|
341 |
|
342 final List<Splittable.SplitRange> ranges = new ArrayList<>(); |
|
343 final List<PropertyNode> properties = objectNode.getElements(); |
|
344 final boolean isSpillObject = properties.size() > CodeGenerator.OBJECT_SPILL_THRESHOLD; |
|
345 long totalWeight = 0; |
|
346 int lo = 0; |
|
347 |
|
348 for (int i = 0; i < properties.size(); i++) { |
|
349 |
|
350 final PropertyNode property = properties.get(i); |
|
351 final boolean isConstant = LiteralNode.isConstant(property.getValue()); |
|
352 |
|
353 if (!isConstant || !isSpillObject) { |
|
354 weight = isConstant ? 0 : WeighNodes.weigh(property.getValue()); |
|
355 totalWeight += WeighNodes.AASTORE_WEIGHT + weight; |
|
356 |
|
357 if (totalWeight >= SPLIT_THRESHOLD) { |
|
358 final CompileUnit unit = compiler.findUnit(totalWeight - weight); |
|
359 ranges.add(new Splittable.SplitRange(unit, lo, i)); |
|
360 lo = i; |
|
361 totalWeight = weight; |
|
362 } |
|
363 } |
|
364 } |
|
365 |
|
366 if (lo != properties.size()) { |
|
367 final CompileUnit unit = compiler.findUnit(totalWeight); |
|
368 ranges.add(new Splittable.SplitRange(unit, lo, properties.size())); |
|
369 } |
|
370 |
|
371 return objectNode.setSplitRanges(lc, ranges); |
327 } |
372 } |
328 |
373 |
329 @Override |
374 @Override |
330 public boolean enterFunctionNode(final FunctionNode node) { |
375 public boolean enterFunctionNode(final FunctionNode node) { |
331 //only go into the function node for this splitter. any subfunctions are rejected |
376 //only go into the function node for this splitter. any subfunctions are rejected |