diff --git a/src/array.c b/src/array.c
index b5dc886fb85f370a55f94a1f5afbeda9714dfab9..512914eb682175a6fe4f05a3919c5e2dac70de67 100644
--- a/src/array.c
+++ b/src/array.c
@@ -1298,7 +1298,7 @@ void gc_check_all_arrays()
   do
   {
     if(a->type_field & BIT_COMPLEX)
-      gc_check_svalues(ITEM(a), a->size);
+      a->type_field = gc_check_svalues(ITEM(a), a->size);
 
     a=a->next;
   } while (a != & empty_array);
diff --git a/src/gc.c b/src/gc.c
index 4e86c01b2e992b6c653a31c03353e4f0ccc057ab..e2ca81baa8b1d5adfc25b41a5a901cebb1c25c5c 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -24,7 +24,7 @@
 
 #define GC_CONST 20
 #define MIN_ALLOC_THRESHOLD 1000
-#defien MAX_ALLOC_THRESHOLD 10000000
+#define MAX_ALLOC_THRESHOLD 10000000
 #define MULTIPLIER 0.9
 #define MARKER_CHUNK_SIZE 1023
 
@@ -239,6 +239,8 @@ void do_gc()
 
   if(alloc_threshold < MIN_ALLOC_THRESHOLD)
     alloc_threshold = MIN_ALLOC_THRESHOLD;
+  if(alloc_threshold > MAX_ALLOC_THRESHOLD)
+    alloc_threshold = MAX_ALLOC_THRESHOLD;
   num_allocs=0;
 
 #ifdef DEBUG
diff --git a/src/las.c b/src/las.c
index 4a34df8a8983939dea31fc6f2e0ed7858a23473d..81bbf3aa3200cfb7135323e145ddf19a032acca6 100644
--- a/src/las.c
+++ b/src/las.c
@@ -108,6 +108,9 @@ INT32 count_args(node *n)
     return tmp2;
   }
 
+  case F_PUSH_ARRAY:
+    return -1;
+
   default:
     if(n->type == void_type_string) return 0;
     return 1;
diff --git a/src/operators.c b/src/operators.c
index b280c5a9ef989c90a24ce02f74838a20c0251d75..60047105fba2bfbc3a2bbe63778750f828dbda43 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -1012,9 +1012,9 @@ void init_operators()
 
   add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and);
 
-  add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);
+  add_efun2("`|",f_or,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);
 
-  add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);
+  add_efun2("`^",f_xor,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);
 
   add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);
   add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
diff --git a/src/svalue.c b/src/svalue.c
index 58b8d82b81637dbeb145fdad58929d88552686e0..3c75166201824d8db0978e200dcc2f57d7dc9d82 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -149,24 +149,25 @@ void free_svalues(struct svalue *s,INT32 num, INT32 type_hint)
   case BIT_FLOAT | BIT_INT:
     return;
 
-#define DOTYPE(X,Y,Z) case X:while(--num>=0)if(s->u.refs--==0) Y(s->u.Z); return
-    DOTYPE(BIT_STRING, really_free_string, string);
-    DOTYPE(BIT_ARRAY, really_free_array, array);
-    DOTYPE(BIT_MAPPING, really_free_mapping, mapping);
-    DOTYPE(BIT_LIST, really_free_list, list);
-    DOTYPE(BIT_OBJECT, really_free_object, object);
-    DOTYPE(BIT_PROGRAM, really_free_program, program);
+#define DOTYPE(X,Y,Z) case X:while(--num>=0) { Y(s->u.Z); s++; }return
+    DOTYPE(BIT_STRING, free_string, string);
+    DOTYPE(BIT_ARRAY, free_array, array);
+    DOTYPE(BIT_MAPPING, free_mapping, mapping);
+    DOTYPE(BIT_LIST, free_list, list);
+    DOTYPE(BIT_OBJECT, free_object, object);
+    DOTYPE(BIT_PROGRAM, free_program, program);
 
   case BIT_FUNCTION:
     while(--num>=0)
     {
-      if(s->u.refs--==0)
+      if(s->u.refs[0]--==0)
       {
 	if(s->subtype == -1)
 	  really_free_callable(s->u.efun);
 	else
 	  really_free_object(s->u.object);
       }
+      s++;
     }
     return;
 
@@ -634,11 +635,14 @@ void check_svalue(struct svalue *s)
 #endif
 
 #ifdef GC2
-void gc_check_svalues(struct svalue *s, int num)
+TYPE_FIELD gc_check_svalues(struct svalue *s, int num)
 {
   INT32 e;
+  TYPE_FIELD f;
+  f=0;
   for(e=0;e<num;e++,s++)
   {
+    f|= 1 << s->type;
     switch(s->type)
     {
     case T_FUNCTION:
@@ -661,6 +665,8 @@ void gc_check_svalues(struct svalue *s, int num)
       break;
     }
   }
+
+  return f;
 }
 
 void gc_check_short_svalue(union anything *u, TYPE_T type)
diff --git a/src/svalue.h b/src/svalue.h
index 80bf0c88f6fdc01752e7d2e0005359878dce2ae5..06095039339dc055ba5a14fecf099266dc194938 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -175,8 +175,10 @@ void copy_svalues_recursively_no_free(struct svalue *to,
 				      struct processing *p);
 void check_short_svalue(union anything *u,TYPE_T type);
 void check_svalue(struct svalue *s);
-void gc_check_svalues(struct svalue *s, int num);
+TYPE_FIELD gc_check_svalues(struct svalue *s, int num);
 void gc_check_short_svalue(union anything *u, TYPE_T type);
+void gc_mark_svalues(struct svalue *s, int num);
+void gc_mark_short_svalue(union anything *u, TYPE_T type);
 /* Prototypes end here */
 
 #endif