[ATL] stack overflow from simple script [message #105690] |
Wed, 27 May 2009 06:38  |
Eclipse User |
|
|
|
Hi all,
I have a simple script (see below) that for each object in the source
model loops over all attributes and produces some output.
This lead to an ArrayOutOfBoundsException in
org.eclipse.m2m.atl.engine.emfvm.ASMOperation
since every result of a println() operation seems to be appended to the
array
final Object[] stack = new Object[MAX_STACK];
For a still small model the frame pointer fp hit the MAX_STACK value of
100. When I increased that to 1000 everything went fine.
I don't know details about the VM implementation but I assume it is a
principle flaw if a nested loop is sort of expanded to a stack?
Can you give me a hint which kind of constructs I have to avoid for not
falling into this kind of pit?
Regards,
Henrik
-------------------------- xrefs_simple.atl ----------------------------
module xrefs_simple;
create OUT : TestSequence from IN : TestInterface;
helper def: xrefs : Map(String, TestInterface!EObject) = Map{};
entrypoint rule createMapAndRoot() {
to
t: TestSequence!PortSequence
do {
'started creating xrefs'.println();
for (e in TestInterface!EObject.allInstancesFrom('IN')) {
'checking object of class: '.concat(e.eClass().getName()).println();
--e.debug('--');
for (a in e.eClass().getEAllAttributes()) {
--a.debug(' attribute ');
' attribute: '.concat(a.getName()).println();
if (a.getName() = 'Typ') {
' got a match'.println();
' value of Typ is: '.concat(e.eGet(a)).println();
thisModule.xrefs <- thisModule.xrefs.including(e.eGet(a), e);
}
}
}
'finished creating xrefs'.println();
}
}
|
|
|
|
|
Re: [ATL] stack overflow from simple script [message #108577 is a reply to message #106372] |
Thu, 23 July 2009 04:16  |
Eclipse User |
|
|
|
Hi all,
I encountered the same problem and had a look at the executed bytecode to
understand what happened.
Indeed, in imperative blocks, any imperative statement which is not an
variable assignement (such as 'toto'.println(); or src.debug();, or even
called rules) pushes its result on the stack. The problem is that this
result is then never used by any other following statement, and the
accumulation of such results progressively leads to a stack overflow.
A workaround to avoid the overflow is to artificially "consume" the result
of such statements, using for instance a sink local variable:
rule model2model {
from src: UML!Model
using {
sinkVar: OclAny = OclUndefined;
}
to dst: UML!Model(
name <- src.name
)
do {
for (t in src.packagedElement->select(elem|
elem.oclIsKindOf(UML!Class)){
for (attr in t.ownedAttribute){
sinkVar<-'--'.println();
sinkVar<- attr.name.debug('attribute name');
}
}
}
}
It permitted me to fix my problem, I should also work for you!
Best regards,
Sebastien
|
|
|
Powered by
FUDForum. Page generated in 0.04347 seconds