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 568776 : OPTgarbageCollectorImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 31 : InstrPtr pci) 32 : { 33 568776 : int i, limit; 34 568776 : InstrPtr p; 35 568776 : int actions = 0; 36 568776 : str msg = MAL_SUCCEED; 37 : 38 568776 : (void) stk; 39 568776 : if (mb->inlineProp) 40 0 : goto wrapup; 41 : 42 568776 : limit = mb->stop; 43 : 44 : 45 : // move SQL query definition to the front for event profiling tools 46 568776 : p = NULL; 47 12504092 : for (i = 0; i < limit; i++) 48 12185172 : if (mb->stmt[i] && getModuleId(mb->stmt[i]) == querylogRef 49 249232 : && getFunctionId(mb->stmt[i]) == defineRef) { 50 : p = getInstrPtr(mb, i); 51 : break; 52 : } 53 : 54 568776 : if (p != NULL) { 55 249864 : for (; i > 1; i--) 56 35 : mb->stmt[i] = mb->stmt[i - 1]; 57 249829 : mb->stmt[1] = p; 58 249829 : actions = 1; 59 : } 60 : // Actual garbage collection stuff, just mark them for re-assessment 61 568776 : p = NULL; 62 17636735 : for (i = 0; i < limit; i++) { 63 17637021 : p = getInstrPtr(mb, i); 64 17637021 : p->gc = false; 65 17637021 : p->typeresolved = false; 66 : /* Set the program counter to ease profiling */ 67 17637021 : p->pc = i; 68 17637021 : 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 568776 : 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 568776 : getInstrPtr(mb, 0)->gc = true; 80 : 81 : /* leave a consistent scope admin behind */ 82 568776 : setVariableScope(mb); 83 : /* Defense line against incorrect plans */ 84 568961 : if (actions > 0) { 85 250014 : if (!msg) 86 250014 : msg = chkTypes(cntxt->usermodule, mb, FALSE); 87 250061 : if (!msg) 88 249851 : msg = chkFlow(mb); 89 250021 : if (!msg) 90 250021 : msg = chkDeclarations(mb); 91 : } 92 : /* keep all actions taken as a post block comment */ 93 318947 : wrapup: 94 : /* keep actions taken as a fake argument */ 95 569330 : (void) pushInt(mb, pci, actions); 96 569330 : return msg; 97 : }