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 : 19 : /* The garbage collector is focused on removing temporary BATs only. 20 : * Leaving some garbage on the stack is an issue. 21 : * 22 : * The end-of-life of a BAT may lay within block bracket. This calls 23 : * for care, as the block may trigger a loop and then the BATs should 24 : * still be there. 25 : * 26 : * The life time of such BATs is forcefully terminated after the block exit. 27 : */ 28 : 29 : str 30 569406 : OPTgarbageCollectorImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 31 : InstrPtr pci) 32 : { 33 569406 : int i, limit; 34 569406 : InstrPtr p; 35 569406 : int actions = 0; 36 569406 : str msg = MAL_SUCCEED; 37 : 38 569406 : (void) stk; 39 569406 : if (mb->inlineProp) 40 0 : goto wrapup; 41 : 42 569406 : limit = mb->stop; 43 : 44 : 45 : // move SQL query definition to the front for event profiling tools 46 569406 : p = NULL; 47 12538004 : for (i = 0; i < limit; i++) 48 12217978 : if (mb->stmt[i] && getModuleId(mb->stmt[i]) == querylogRef 49 248926 : && getFunctionId(mb->stmt[i]) == defineRef) { 50 : p = getInstrPtr(mb, i); 51 : break; 52 : } 53 : 54 569406 : if (p != NULL) { 55 249510 : for (; i > 1; i--) 56 35 : mb->stmt[i] = mb->stmt[i - 1]; 57 249475 : mb->stmt[1] = p; 58 249475 : actions = 1; 59 : } 60 : // Actual garbage collection stuff, just mark them for re-assessment 61 569406 : p = NULL; 62 17656146 : for (i = 0; i < limit; i++) { 63 17656681 : p = getInstrPtr(mb, i); 64 17656681 : p->gc = false; 65 17656681 : p->typeresolved = false; 66 : /* Set the program counter to ease profiling */ 67 17656681 : p->pc = i; 68 17656681 : if (p->token == ENDsymbol) 69 : break; 70 : } 71 : 72 : //mnstr_printf(cntxt->fdout,"garbacollector limit %d ssize %d vtop %d vsize %d\n", limit, (int)(mb->ssize), mb->vtop, (int)(mb->vsize)); 73 : /* A good MAL plan should end with an END instruction */ 74 569406 : if (p && p->token != ENDsymbol) { 75 0 : throw(MAL, "optimizer.garbagecollector", 76 : SQLSTATE(42000) "Incorrect MAL plan encountered"); 77 : } 78 : /* move sanity check to other optimizer */ 79 569406 : getInstrPtr(mb, 0)->gc = true; 80 : 81 : /* leave a consistent scope admin behind */ 82 569406 : setVariableScope(mb); 83 : /* Defense line against incorrect plans */ 84 569869 : if (actions > 0) { 85 249938 : if (!msg) 86 249938 : msg = chkTypes(cntxt->usermodule, mb, FALSE); 87 249966 : if (!msg) 88 249720 : msg = chkFlow(mb); 89 250005 : if (!msg) 90 250005 : msg = chkDeclarations(mb); 91 : } 92 : /* keep all actions taken as a post block comment */ 93 319931 : wrapup: 94 : /* keep actions taken as a fake argument */ 95 570332 : (void) pushInt(mb, pci, actions); 96 570332 : return msg; 97 : }