Line data Source code
1 : /* 2 : * SPDX-License-Identifier: MPL-2.0 3 : * 4 : * This Source Code Form is subject to the terms of the Mozilla Public 5 : * License, v. 2.0. If a copy of the MPL was not distributed with this 6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 : * 8 : * Copyright 2024 MonetDB Foundation; 9 : * Copyright August 2008 - 2023 MonetDB B.V.; 10 : * Copyright 1997 - July 2008 CWI. 11 : */ 12 : 13 : #include "monetdb_config.h" 14 : #include "opt_garbageCollector.h" 15 : #include "mal_interpreter.h" 16 : #include "mal_builder.h" 17 : #include "mal_function.h" 18 : #include "opt_prelude.h" 19 : 20 : /* The garbage collector is focused on removing temporary BATs only. 21 : * Leaving some garbage on the stack is an issue. 22 : * 23 : * The end-of-life of a BAT may lay within block bracket. This calls 24 : * for care, as the block may trigger a loop and then the BATs should 25 : * still be there. 26 : * 27 : * The life time of such BATs is forcefully terminated after the block exit. 28 : */ 29 : 30 : str 31 554468 : OPTgarbageCollectorImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 32 : InstrPtr pci) 33 : { 34 554468 : int i, limit; 35 554468 : InstrPtr p; 36 554468 : int actions = 0; 37 554468 : str msg = MAL_SUCCEED; 38 : 39 554468 : (void) stk; 40 554468 : if (mb->inlineProp) 41 0 : goto wrapup; 42 : 43 554468 : limit = mb->stop; 44 : 45 : 46 : // move SQL query definition to the front for event profiling tools 47 554468 : p = NULL; 48 11663520 : for (i = 0; i < limit; i++) 49 11358424 : if (mb->stmt[i] && getModuleId(mb->stmt[i]) == querylogRef 50 249374 : && getFunctionId(mb->stmt[i]) == defineRef) { 51 : p = getInstrPtr(mb, i); 52 : break; 53 : } 54 : 55 554468 : if (p != NULL) { 56 249407 : for (; i > 1; i--) 57 35 : mb->stmt[i] = mb->stmt[i - 1]; 58 249372 : mb->stmt[1] = p; 59 249372 : actions = 1; 60 : } 61 : // Actual garbage collection stuff, just mark them for re-assessment 62 554468 : p = NULL; 63 12203223 : for (i = 0; i < limit; i++) { 64 12203219 : p = getInstrPtr(mb, i); 65 12203219 : p->gc = false; 66 12203219 : p->typeresolved = false; 67 : /* Set the program counter to ease profiling */ 68 12203219 : p->pc = i; 69 12203219 : if (p->token == ENDsymbol) 70 : break; 71 : } 72 : 73 : //mnstr_printf(cntxt->fdout,"garbacollector limit %d ssize %d vtop %d vsize %d\n", limit, (int)(mb->ssize), mb->vtop, (int)(mb->vsize)); 74 : /* A good MAL plan should end with an END instruction */ 75 554468 : if (p && p->token != ENDsymbol) { 76 0 : throw(MAL, "optimizer.garbagecollector", 77 : SQLSTATE(42000) "Incorrect MAL plan encountered"); 78 : } 79 : /* move sanity check to other optimizer */ 80 554468 : getInstrPtr(mb, 0)->gc = true; 81 : 82 : /* leave a consistent scope admin behind */ 83 554468 : setVariableScope(mb); 84 : /* Defense line against incorrect plans */ 85 554462 : if (actions > 0) { 86 249366 : if (!msg) 87 249366 : msg = chkTypes(cntxt->usermodule, mb, FALSE); 88 249362 : if (!msg) 89 249362 : msg = chkFlow(mb); 90 249370 : if (!msg) 91 249370 : msg = chkDeclarations(mb); 92 : } 93 : /* keep all actions taken as a post block comment */ 94 305096 : wrapup: 95 : /* keep actions taken as a fake argument */ 96 554462 : (void) pushInt(mb, pci, actions); 97 554462 : return msg; 98 : }