Changeset: b859d97e430c for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b859d97e430c
Modified Files:
monetdb5/mal/mal_box.mx
monetdb5/mal/mal_interpreter.mx
monetdb5/mal/mal_resolve.mx
monetdb5/mal/mal_stack.c
sql/backends/monet5/datacell/datacell.c
Branch: Aug2011
Log Message:
Backed out changeset 889a048ea303
In order to solve a merge gone bad.
diffs (truncated from 1662 to 300 lines):
diff --git a/monetdb5/mal/mal_box.mx b/monetdb5/mal/mal_box.mx
--- a/monetdb5/mal/mal_box.mx
+++ b/monetdb5/mal/mal_box.mx
@@ -425,8 +425,7 @@
return 0;
if (i < 0) {
i = newVariable(box->sym, GDKstrdup(name), type);
- if (box->val->stksize <= i)
- box->val =reallocStack(box->val, STACKINCR);
+ chkStack(box->val, i);
}
v = &box->val->stk[i];
VALclear(v);
diff --git a/monetdb5/mal/mal_interpreter.mx b/monetdb5/mal/mal_interpreter.mx
--- a/monetdb5/mal/mal_interpreter.mx
+++ b/monetdb5/mal/mal_interpreter.mx
@@ -448,9 +448,9 @@
#if FAST
int stamp = -1;
#endif
- bat *backup = (bat*)GDKzalloc(mb->maxarg * sizeof(bat));
- str *sbackup = (str*)GDKzalloc(mb->maxarg * sizeof(str));
- int *garbage = (int*)GDKzalloc(mb->maxarg * sizeof(int));
+ bat *backup = (bat*)alloca(mb->maxarg * sizeof(bat));
+ str *sbackup = (str*)alloca(mb->maxarg * sizeof(str));
+ int *garbage = (int*)alloca(mb->maxarg * sizeof(int));
lng oldtimer = 0;
struct Mallinfo oldMemory;
int stkpc = 0;
@@ -544,9 +544,6 @@
}
}
@:MALwrapup@
- GDKfree(backup);
- GDKfree(sbackup);
- GDKfree(garbage);
return ret;
}
@h
@@ -923,9 +920,9 @@
#if FAST
int stamp = -1;
#endif
- bat *backup = (bat*)GDKzalloc(fs->mb->maxarg * sizeof(bat));
- str *sbackup = (str*)GDKzalloc(fs->mb->maxarg * sizeof(str));
- int *garbage = (int*)GDKzalloc(fs->mb->maxarg * sizeof(int));
+ bat *backup = (bat*)alloca(fs->mb->maxarg * sizeof(bat));
+ str *sbackup = (str*)alloca(fs->mb->maxarg * sizeof(str));
+ int *garbage = (int*)alloca(fs->mb->maxarg * sizeof(int));
Client cntxt = fs->cntxt;
MalBlkPtr mb = fs->mb;
MalStkPtr stk = fs->stk;
@@ -968,9 +965,6 @@
/* need a way to skip */
stkpc = mb->stop;
fs->state = -1;
- GDKfree(backup);
- GDKfree(sbackup);
- GDKfree(garbage);
return ret;
}
if (oldtimer) {
@@ -996,19 +990,19 @@
*/
switch (pci->token) {
case ASSIGNsymbol:
- @:assignStmt(FAST,fs->pc = -fs->pc; GDKfree(backup);
GDKfree(sbackup);GDKfree(garbage); return ret,t)@
+ @:assignStmt(FAST,fs->pc = -fs->pc; return ret,t)@
break;
case PATcall:
- @:patterncall(FAST,fs->pc = -fs->pc; GDKfree(backup);
GDKfree(sbackup);GDKfree(garbage); return ret,t)@
+ @:patterncall(FAST,fs->pc = -fs->pc; return ret,t)@
break;
case CMDcall:
- @:commandcall(FAST,fs->pc = -fs->pc; GDKfree(backup);
GDKfree(sbackup);GDKfree(garbage); return ret,t)@
+ @:commandcall(FAST,fs->pc = -fs->pc; return ret,t)@
break;
case FACcall:
- @:factorycall(FAST,fs->pc = -fs->pc; GDKfree(backup);
GDKfree(sbackup);GDKfree(garbage); return ret,t)@
+ @:factorycall(FAST,fs->pc = -fs->pc; return ret,t)@
break;
case FCNcall:
- @:functioncall(FAST,fs->pc = -fs->pc; GDKfree(backup);
GDKfree(sbackup);GDKfree(garbage); return ret,t)@
+ @:functioncall(FAST,fs->pc = -fs->pc; return ret,t)@
break;
case NOOPsymbol:
case REMsymbol:
@@ -1025,9 +1019,6 @@
@:endProfile(t)@
if (ret)
fs->pc = -fs->pc;
- GDKfree(backup);
- GDKfree(sbackup);
- GDKfree(garbage);
return ret;
}
diff --git a/monetdb5/mal/mal_resolve.mx b/monetdb5/mal/mal_resolve.mx
--- a/monetdb5/mal/mal_resolve.mx
+++ b/monetdb5/mal/mal_resolve.mx
@@ -17,64 +17,65 @@
All Rights Reserved.
@
-@a M. Kersten
-@v 1.0
-@+ Type Resolution
-Given the interpretative nature of many of the MAL instructions,
-when and where type resolution takes place is a critical design issue.
-Performing it too late, i.e. at each instruction call, leads to
-performance problems if we derive the same information over and over again.
-However, many built-in operators have polymorphic typed signatures,
-so we cannot escape it altogether.
-
-Consider the small illustrative MAL program:
-@example
-function sample(nme:str, val:any_1):bit;
- c := 2 * 3;
- b := bbp.bind(nme); #find a BAT
- h := algebra.select(b,val,val);
- t := aggr.count(h);
- x := io.print(t);
- y := io.print(val);
-end sample;
-@end example
-@-
-The function definition is polymorphic typed on the 2nd argument,
-it becomes a concrete type upon invocation. The system could attempt
-a type check, but quickly runs into assumptions that generally do not hold.
-The first assignment can be type checked during parsing
-and a symbolic optimizer could even evaluate the expression once.
-Looking up a BAT in the buffer pool leads to
-an element @sc{:bat[@emph{ht,tt}]} where @emph{ht} and @emph{tt}
-are runtime dependent types, which means that the selection operation can
-not be type-checked immediately. It is an example of an embedded
-polypmorphic statement, which requires intervention of the user/optimizer
-to make the type explicit before the type resolver becomes active.
-The operation @sc{count} can be checked, if it is given a BAT argument.
-This assumes that we can infer that 'h' is indeed a BAT, which requires
-assurance that @sc{algebra.select} produces one. However, there are
-no rules to avoid addition of new operators, or to differentiate among
-different implementations based on the argument types.
-Since @sc{print(t)} contains an undetermined typed
-argument we should postpone typechecking as well.
-The last print statement can be checked upon function invocation.
-
-Life becomes really complex if the body contains a loop with
-variable types. For then we also have to keep track of the original
-state of the function. Or alternatively, type checking should consider
-the runtime stack rather than the function definition itself.
-
-These examples give little room to achieve our prime objective, i.e.
-a fast and early type resolution scheme. Any non-polymorphic function
-can be type checked and marked type-safe upon completion.
-Type checking polymorphic functions are post-poned until a concrete
-type instance is known. It leads to a clone, which can be type checked
-and is entered into the symbol table.
-@{
-The type resolution status is marked in each instruction.
-TYPE_RESOLVED implies that the type of the instruction is fully
-resolved, it is marked TYPE_DYNAMIC otherwise.
-
+@c
+/*
+ * @a M. Kersten
+ * @v 1.0
+ * @+ Type Resolution
+ * Given the interpretative nature of many of the MAL instructions,
+ * when and where type resolution takes place is a critical design issue.
+ * Performing it too late, i.e. at each instruction call, leads to
+ * performance problems if we derive the same information over and over again.
+ * However, many built-in operators have polymorphic typed signatures,
+ * so we cannot escape it altogether.
+ *
+ * Consider the small illustrative MAL program:
+ * @example
+ * function sample(nme:str, val:any_1):bit;
+ * c := 2 * 3;
+ * b := bbp.bind(nme); #find a BAT
+ * h := algebra.select(b,val,val);
+ * t := aggr.count(h);
+ * x := io.print(t);
+ * y := io.print(val);
+ * end sample;
+ * @end example
+ * @-
+ * The function definition is polymorphic typed on the 2nd argument,
+ * it becomes a concrete type upon invocation. The system could attempt
+ * a type check, but quickly runs into assumptions that generally do not hold.
+ * The first assignment can be type checked during parsing
+ * and a symbolic optimizer could even evaluate the expression once.
+ * Looking up a BAT in the buffer pool leads to
+ * an element @sc{:bat[@emph{ht,tt}]} where @emph{ht} and @emph{tt}
+ * are runtime dependent types, which means that the selection operation can
+ * not be type-checked immediately. It is an example of an embedded
+ * polypmorphic statement, which requires intervention of the user/optimizer
+ * to make the type explicit before the type resolver becomes active.
+ * The operation @sc{count} can be checked, if it is given a BAT argument.
+ * This assumes that we can infer that 'h' is indeed a BAT, which requires
+ * assurance that @sc{algebra.select} produces one. However, there are
+ * no rules to avoid addition of new operators, or to differentiate among
+ * different implementations based on the argument types.
+ * Since @sc{print(t)} contains an undetermined typed
+ * argument we should postpone typechecking as well.
+ * The last print statement can be checked upon function invocation.
+ *
+ * Life becomes really complex if the body contains a loop with
+ * variable types. For then we also have to keep track of the original
+ * state of the function. Or alternatively, type checking should consider
+ * the runtime stack rather than the function definition itself.
+ *
+ * These examples give little room to achieve our prime objective, i.e.
+ * a fast and early type resolution scheme. Any non-polymorphic function
+ * can be type checked and marked type-safe upon completion.
+ * Type checking polymorphic functions are post-poned until a concrete
+ * type instance is known. It leads to a clone, which can be type checked
+ * and is entered into the symbol table.
+ * The type resolution status is marked in each instruction.
+ * TYPE_RESOLVED implies that the type of the instruction is fully
+ * resolved, it is marked TYPE_DYNAMIC otherwise.
+ */
@h
#ifndef _MAL_RESOLVE_H
#define _MAL_RESOLVE_H
@@ -100,14 +101,15 @@
mal_export void expandMacro(MalBlkPtr mb, InstrPtr p, MalBlkPtr mc);
#endif /* _MAL_RESOLVE_H*/
-@- Function call resolution
-Search the first definition of the operator in the current module
-and check the parameter types.
-For a polymorphic MAL function we make a fully instantiated clone.
-It will be prepended to the symbol list as it is more restrictive.
-This effectively overloads the MAL procedure.
-
@c
+/*
+ * @- Function call resolution
+ * Search the first definition of the operator in the current module
+ * and check the parameter types.
+ * For a polymorphic MAL function we make a fully instantiated clone.
+ * It will be prepended to the symbol list as it is more restrictive.
+ * This effectively overloads the MAL procedure.
+ */
#include "monetdb_config.h"
#include "mal_resolve.h"
#include "mal_namespace.h"
@@ -128,420 +130,441 @@
}
#endif
-static malType findFunctionType(Module scope, MalBlkPtr mb, InstrPtr p,int
silent){
+static malType
+findFunctionType(Module scope, MalBlkPtr mb, InstrPtr p, int silent)
+{
Module m;
Symbol s;
InstrPtr sig;
- int i,k, unmatched = 0, s1;
+ int i, k, unmatched = 0, s1;
/* int foundbutwrong=0;*/
int polytype[MAXTYPEVAR];
- int *returntype= NULL;;
-@-
-Within a module find the subscope to locate the element in its list
-of symbols. A skiplist is used to speed up the search for the
-definition of the function.
-
-For the implementation we should be aware that over 90% of the
-functions in the kernel have just a few arguments and a single
-return value.
-A point of concern is that polymorphic arithmetic operations
-lead to an explosion in the symbol table. This increase the
-loop to find a candidate.
-
-Consider to collect the argument type into a separate structure, because
-it will be looked up multiple types to resolve the instruction.[todo]
-Simplify polytype using a map into the concrete argument table.
-@c
- m= scope;
- s= m->subscope[(int)(getSubScope(getFunctionId(p)))];
- if( s == 0) return -1;
- while(s != NULL){ /* single scope element check */
- if( getFunctionId(p) != s->name ){
- s= s->skip; continue;
- }
-@-
-Perform a strong type-check on the actual arguments. If it turns
-out to be a polymorphic MAL function, we have to clone it.
-Provided the actual/formal parameters are compliant throughout
-the function call.
-
-Also look out for variable argument lists. This means that we
-have to keep two iterators, one for the caller (i) and one for
-the callee (k). Since a variable argument only occurs as the last one,
-we simple avoid an increment when running out of formal arguments.
-
-A call of the form (X1,..., Xi) := f(Y1,....,Yn) can be matched against
-the function signature (B1,...,Bk):= f(A1,...,Am) where i==k , n<=m
-and type(Ai)=type(Yi). Furthermore, the variables Xi obtain their type
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list