commandLineFlagConstraintList.cpp revision 9149:a8a8604f890f
1220496Smarkm/*
2220496Smarkm * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3220496Smarkm * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4220496Smarkm *
5220496Smarkm * This code is free software; you can redistribute it and/or modify it
6220496Smarkm * under the terms of the GNU General Public License version 2 only, as
7220496Smarkm * published by the Free Software Foundation.
8220496Smarkm *
9220496Smarkm * This code is distributed in the hope that it will be useful, but WITHOUT
10220496Smarkm * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11220496Smarkm * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12220496Smarkm * version 2 for more details (a copy is included in the LICENSE file that
13220496Smarkm * accompanied this code).
14220496Smarkm *
15220496Smarkm * You should have received a copy of the GNU General Public License version
16220496Smarkm * 2 along with this work; if not, write to the Free Software Foundation,
17220496Smarkm * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18220496Smarkm *
19220496Smarkm * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20220496Smarkm * or visit www.oracle.com if you need additional information or have any
21220496Smarkm * questions.
22220496Smarkm *
23220496Smarkm */
24220496Smarkm
25220496Smarkm#include "precompiled.hpp"
26220496Smarkm#include "classfile/stringTable.hpp"
27220496Smarkm#include "classfile/symbolTable.hpp"
28220496Smarkm#include "gc/shared/referenceProcessor.hpp"
29220496Smarkm#include "runtime/arguments.hpp"
30220496Smarkm#include "runtime/commandLineFlagConstraintList.hpp"
31220496Smarkm#include "runtime/commandLineFlagConstraintsCompiler.hpp"
32220496Smarkm#include "runtime/commandLineFlagConstraintsGC.hpp"
33220496Smarkm#include "runtime/commandLineFlagConstraintsRuntime.hpp"
34220496Smarkm#include "runtime/os.hpp"
35220496Smarkm#include "utilities/macros.hpp"
36220496Smarkm#if INCLUDE_JVMCI
37220496Smarkm#include "jvmci/commandLineFlagConstraintsJVMCI.hpp"
38220496Smarkm#endif
39220496Smarkm
40220496Smarkmclass CommandLineFlagConstraint_bool : public CommandLineFlagConstraint {
41220496Smarkm  CommandLineFlagConstraintFunc_bool _constraint;
42220496Smarkm
43220496Smarkmpublic:
44220496Smarkm  // the "name" argument must be a string literal
45220496Smarkm  CommandLineFlagConstraint_bool(const char* name,
46220496Smarkm                                 CommandLineFlagConstraintFunc_bool func,
47220496Smarkm                                 ConstraintType type) : CommandLineFlagConstraint(name, type) {
48220496Smarkm    _constraint=func;
49220496Smarkm  }
50220496Smarkm
51220496Smarkm  Flag::Error apply_bool(bool value, bool verbose) {
52220496Smarkm    return _constraint(value, verbose);
53220496Smarkm  }
54220496Smarkm};
55220496Smarkm
56220496Smarkmclass CommandLineFlagConstraint_int : public CommandLineFlagConstraint {
57220496Smarkm  CommandLineFlagConstraintFunc_int _constraint;
58220496Smarkm
59220496Smarkmpublic:
60220496Smarkm  // the "name" argument must be a string literal
61220496Smarkm  CommandLineFlagConstraint_int(const char* name,
62220496Smarkm                                CommandLineFlagConstraintFunc_int func,
63220496Smarkm                                ConstraintType type) : CommandLineFlagConstraint(name, type) {
64220496Smarkm    _constraint=func;
65220496Smarkm  }
66220496Smarkm
67220496Smarkm  Flag::Error apply_int(int value, bool verbose) {
68220496Smarkm    return _constraint(value, verbose);
69220496Smarkm  }
70220496Smarkm};
71220496Smarkm
72220496Smarkmclass CommandLineFlagConstraint_intx : public CommandLineFlagConstraint {
73220496Smarkm  CommandLineFlagConstraintFunc_intx _constraint;
74220496Smarkm
75220496Smarkmpublic:
76220496Smarkm  // the "name" argument must be a string literal
77220496Smarkm  CommandLineFlagConstraint_intx(const char* name,
78220496Smarkm                                 CommandLineFlagConstraintFunc_intx func,
79220496Smarkm                                 ConstraintType type) : CommandLineFlagConstraint(name, type) {
80220496Smarkm    _constraint=func;
81220496Smarkm  }
82220496Smarkm
83220496Smarkm  Flag::Error apply_intx(intx value, bool verbose) {
84220496Smarkm    return _constraint(value, verbose);
85220496Smarkm  }
86220496Smarkm};
87220496Smarkm
88220496Smarkmclass CommandLineFlagConstraint_uint : public CommandLineFlagConstraint {
89220496Smarkm  CommandLineFlagConstraintFunc_uint _constraint;
90220496Smarkm
91220496Smarkmpublic:
92220496Smarkm  // the "name" argument must be a string literal
93220496Smarkm  CommandLineFlagConstraint_uint(const char* name,
94220496Smarkm                                 CommandLineFlagConstraintFunc_uint func,
95220496Smarkm                                 ConstraintType type) : CommandLineFlagConstraint(name, type) {
96220496Smarkm    _constraint=func;
97220496Smarkm  }
98220496Smarkm
99220496Smarkm  Flag::Error apply_uint(uint value, bool verbose) {
100220496Smarkm    return _constraint(value, verbose);
101220496Smarkm  }
102220496Smarkm};
103220496Smarkm
104220496Smarkmclass CommandLineFlagConstraint_uintx : public CommandLineFlagConstraint {
105220496Smarkm  CommandLineFlagConstraintFunc_uintx _constraint;
106220496Smarkm
107220496Smarkmpublic:
108220496Smarkm  // the "name" argument must be a string literal
109220496Smarkm  CommandLineFlagConstraint_uintx(const char* name,
110220496Smarkm                                  CommandLineFlagConstraintFunc_uintx func,
111220496Smarkm                                  ConstraintType type) : CommandLineFlagConstraint(name, type) {
112220496Smarkm    _constraint=func;
113220496Smarkm  }
114220496Smarkm
115220496Smarkm  Flag::Error apply_uintx(uintx value, bool verbose) {
116220496Smarkm    return _constraint(value, verbose);
117220496Smarkm  }
118220496Smarkm};
119220496Smarkm
120220496Smarkmclass CommandLineFlagConstraint_uint64_t : public CommandLineFlagConstraint {
121220496Smarkm  CommandLineFlagConstraintFunc_uint64_t _constraint;
122220496Smarkm
123220496Smarkmpublic:
124220496Smarkm  // the "name" argument must be a string literal
125220496Smarkm  CommandLineFlagConstraint_uint64_t(const char* name,
126220496Smarkm                                     CommandLineFlagConstraintFunc_uint64_t func,
127220496Smarkm                                     ConstraintType type) : CommandLineFlagConstraint(name, type) {
128220496Smarkm    _constraint=func;
129220496Smarkm  }
130220496Smarkm
131220496Smarkm  Flag::Error apply_uint64_t(uint64_t value, bool verbose) {
132220496Smarkm    return _constraint(value, verbose);
133220496Smarkm  }
134220496Smarkm};
135220496Smarkm
136220496Smarkmclass CommandLineFlagConstraint_size_t : public CommandLineFlagConstraint {
137220496Smarkm  CommandLineFlagConstraintFunc_size_t _constraint;
138220496Smarkm
139220496Smarkmpublic:
140220496Smarkm  // the "name" argument must be a string literal
141220496Smarkm  CommandLineFlagConstraint_size_t(const char* name,
142220496Smarkm                                   CommandLineFlagConstraintFunc_size_t func,
143220496Smarkm                                   ConstraintType type) : CommandLineFlagConstraint(name, type) {
144220496Smarkm    _constraint=func;
145220496Smarkm  }
146220496Smarkm
147220496Smarkm  Flag::Error apply_size_t(size_t value, bool verbose) {
148220496Smarkm    return _constraint(value, verbose);
149220496Smarkm  }
150220496Smarkm};
151220496Smarkm
152220496Smarkmclass CommandLineFlagConstraint_double : public CommandLineFlagConstraint {
153220496Smarkm  CommandLineFlagConstraintFunc_double _constraint;
154220496Smarkm
155220496Smarkmpublic:
156220496Smarkm  // the "name" argument must be a string literal
157220496Smarkm  CommandLineFlagConstraint_double(const char* name,
158220496Smarkm                                   CommandLineFlagConstraintFunc_double func,
159220496Smarkm                                   ConstraintType type) : CommandLineFlagConstraint(name, type) {
160220496Smarkm    _constraint=func;
161220496Smarkm  }
162220496Smarkm
163220496Smarkm  Flag::Error apply_double(double value, bool verbose) {
164220496Smarkm    return _constraint(value, verbose);
165220496Smarkm  }
166220496Smarkm};
167220496Smarkm
168220496Smarkm// No constraint emitting
169220496Smarkmvoid emit_constraint_no(...)                          { /* NOP */ }
170220496Smarkm
171220496Smarkm// No constraint emitting if function argument is NOT provided
172220496Smarkmvoid emit_constraint_bool(const char* /*name*/)       { /* NOP */ }
173220496Smarkmvoid emit_constraint_ccstr(const char* /*name*/)      { /* NOP */ }
174220496Smarkmvoid emit_constraint_ccstrlist(const char* /*name*/)  { /* NOP */ }
175220496Smarkmvoid emit_constraint_int(const char* /*name*/)        { /* NOP */ }
176220496Smarkmvoid emit_constraint_intx(const char* /*name*/)       { /* NOP */ }
177220496Smarkmvoid emit_constraint_uint(const char* /*name*/)       { /* NOP */ }
178220496Smarkmvoid emit_constraint_uintx(const char* /*name*/)      { /* NOP */ }
179220496Smarkmvoid emit_constraint_uint64_t(const char* /*name*/)   { /* NOP */ }
180220496Smarkmvoid emit_constraint_size_t(const char* /*name*/)     { /* NOP */ }
181220496Smarkmvoid emit_constraint_double(const char* /*name*/)     { /* NOP */ }
182220496Smarkm
183220496Smarkm// CommandLineFlagConstraint emitting code functions if function argument is provided
184220496Smarkmvoid emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func, CommandLineFlagConstraint::ConstraintType type) {
185220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func, type));
186220496Smarkm}
187220496Smarkmvoid emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func, CommandLineFlagConstraint::ConstraintType type) {
188220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func, type));
189220496Smarkm}
190220496Smarkmvoid emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func, CommandLineFlagConstraint::ConstraintType type) {
191220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func, type));
192220496Smarkm}
193220496Smarkmvoid emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func, CommandLineFlagConstraint::ConstraintType type) {
194220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func, type));
195220496Smarkm}
196220496Smarkmvoid emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func, CommandLineFlagConstraint::ConstraintType type) {
197220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func, type));
198220496Smarkm}
199220496Smarkmvoid emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func, CommandLineFlagConstraint::ConstraintType type) {
200220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func, type));
201220496Smarkm}
202220496Smarkmvoid emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func, CommandLineFlagConstraint::ConstraintType type) {
203220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func, type));
204220496Smarkm}
205220496Smarkmvoid emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func, CommandLineFlagConstraint::ConstraintType type) {
206220496Smarkm  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func, type));
207220496Smarkm}
208220496Smarkm
209220496Smarkm// Generate code to call emit_constraint_xxx function
210220496Smarkm#define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc)      ); emit_constraint_##type(#name
211220496Smarkm#define EMIT_CONSTRAINT_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
212220496Smarkm#define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
213220496Smarkm#define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name
214220496Smarkm#define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
215220496Smarkm#define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
216220496Smarkm#define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc)          ); emit_constraint_##type(#name
217220496Smarkm#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    ); emit_constraint_##type(#name
218220496Smarkm#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_constraint_##type(#name
219220496Smarkm#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
220220496Smarkm#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name
221220496Smarkm
222220496Smarkm// Generate func argument to pass into emit_constraint_xxx functions
223220496Smarkm#define EMIT_CONSTRAINT_CHECK(func, type)                               , func, CommandLineFlagConstraint::type
224220496Smarkm
225220496Smarkm// the "name" argument must be a string literal
226220496Smarkm#define INITIAL_CONSTRAINTS_SIZE 40
227220496SmarkmGrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL;
228220496SmarkmCommandLineFlagConstraint::ConstraintType CommandLineFlagConstraintList::_validating_type = CommandLineFlagConstraint::AtParse;
229220496Smarkm
230220496Smarkm// Check the ranges of all flags that have them or print them out and exit if requested
231220496Smarkmvoid CommandLineFlagConstraintList::init(void) {
232220496Smarkm  _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, true);
233220496Smarkm
234220496Smarkm  emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
235220496Smarkm                                        EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
236220496Smarkm                                        EMIT_CONSTRAINT_PRODUCT_FLAG,
237220496Smarkm                                        EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
238220496Smarkm                                        EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
239220496Smarkm                                        EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
240220496Smarkm                                        EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
241220496Smarkm                                        EMIT_CONSTRAINT_MANAGEABLE_FLAG,
242220496Smarkm                                        EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
243220496Smarkm                                        EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
244220496Smarkm                                        IGNORE_RANGE,
245220496Smarkm                                        EMIT_CONSTRAINT_CHECK));
246220496Smarkm
247220496Smarkm  EMIT_CONSTRAINTS_FOR_GLOBALS_EXT
248220496Smarkm
249220496Smarkm  emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
250220496Smarkm                                     EMIT_CONSTRAINT_PRODUCT_FLAG,
251220496Smarkm                                     EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
252220496Smarkm                                     EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
253220496Smarkm                                     EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
254220496Smarkm                                     IGNORE_RANGE,
255220496Smarkm                                     EMIT_CONSTRAINT_CHECK));
256220496Smarkm
257220496Smarkm#if INCLUDE_JVMCI
258220496Smarkm  emit_constraint_no(NULL JVMCI_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
259220496Smarkm                                      EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
260220496Smarkm                                      EMIT_CONSTRAINT_PRODUCT_FLAG,
261220496Smarkm                                      EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
262220496Smarkm                                      EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
263220496Smarkm                                      EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
264220496Smarkm                                      EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
265220496Smarkm                                      IGNORE_RANGE,
266220496Smarkm                                      EMIT_CONSTRAINT_CHECK));
267220496Smarkm#endif // INCLUDE_JVMCI
268220496Smarkm
269220496Smarkm#ifdef COMPILER1
270220496Smarkm  emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
271220496Smarkm                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
272220496Smarkm                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
273220496Smarkm                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
274220496Smarkm                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
275220496Smarkm                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
276220496Smarkm                                   IGNORE_RANGE,
277220496Smarkm                                   EMIT_CONSTRAINT_CHECK));
278220496Smarkm#endif // COMPILER1
279220496Smarkm
280220496Smarkm#ifdef COMPILER2
281220496Smarkm  emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
282220496Smarkm                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
283220496Smarkm                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
284220496Smarkm                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
285220496Smarkm                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
286220496Smarkm                                   EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
287220496Smarkm                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
288220496Smarkm                                   IGNORE_RANGE,
289220496Smarkm                                   EMIT_CONSTRAINT_CHECK));
290220496Smarkm#endif // COMPILER2
291220496Smarkm
292220496Smarkm#if INCLUDE_ALL_GCS
293220496Smarkm  emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
294220496Smarkm                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
295220496Smarkm                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
296220496Smarkm                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
297220496Smarkm                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
298220496Smarkm                                   EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
299220496Smarkm                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
300220496Smarkm                                   EMIT_CONSTRAINT_MANAGEABLE_FLAG,
301220496Smarkm                                   EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
302220496Smarkm                                   IGNORE_RANGE,
303220496Smarkm                                   EMIT_CONSTRAINT_CHECK));
304220496Smarkm#endif // INCLUDE_ALL_GCS
305220496Smarkm}
306220496Smarkm
307220496Smarkm// Find constraints by name and return only if found constraint's type is equal or lower than current validating type.
308220496SmarkmCommandLineFlagConstraint* CommandLineFlagConstraintList::find_if_needs_check(const char* name) {
309220496Smarkm  CommandLineFlagConstraint* found = NULL;
310220496Smarkm  for (int i=0; i<length(); i++) {
311220496Smarkm    CommandLineFlagConstraint* constraint = at(i);
312220496Smarkm    if ((strcmp(constraint->name(), name) == 0) &&
313220496Smarkm        (constraint->type() <= _validating_type)) {
314220496Smarkm      found = constraint;
315220496Smarkm      break;
316220496Smarkm    }
317220496Smarkm  }
318220496Smarkm  return found;
319220496Smarkm}
320220496Smarkm
321// Check constraints for specific constraint type.
322bool CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::ConstraintType type) {
323  guarantee(type > _validating_type, "Constraint check is out of order.");
324  _validating_type = type;
325
326  bool status = true;
327  for (int i=0; i<length(); i++) {
328    CommandLineFlagConstraint* constraint = at(i);
329    if (type != constraint->type()) continue;
330    const char* name = constraint->name();
331    Flag* flag = Flag::find_flag(name, strlen(name), true, true);
332    // We must check for NULL here as lp64_product flags on 32 bit architecture
333    // can generate constraint check (despite that they are declared as constants),
334    // but they will not be returned by Flag::find_flag()
335    if (flag != NULL) {
336      if (flag->is_bool()) {
337        bool value = flag->get_bool();
338        if (constraint->apply_bool(value, true) != Flag::SUCCESS) status = false;
339      } else if (flag->is_int()) {
340        int value = flag->get_int();
341        if (constraint->apply_int(value, true) != Flag::SUCCESS) status = false;
342      } else if (flag->is_uint()) {
343        uint value = flag->get_uint();
344        if (constraint->apply_uint(value, true) != Flag::SUCCESS) status = false;
345      } else if (flag->is_intx()) {
346        intx value = flag->get_intx();
347        if (constraint->apply_intx(value, true) != Flag::SUCCESS) status = false;
348      } else if (flag->is_uintx()) {
349        uintx value = flag->get_uintx();
350        if (constraint->apply_uintx(value, true) != Flag::SUCCESS) status = false;
351      } else if (flag->is_uint64_t()) {
352        uint64_t value = flag->get_uint64_t();
353        if (constraint->apply_uint64_t(value, true) != Flag::SUCCESS) status = false;
354      } else if (flag->is_size_t()) {
355        size_t value = flag->get_size_t();
356        if (constraint->apply_size_t(value, true) != Flag::SUCCESS) status = false;
357      } else if (flag->is_double()) {
358        double value = flag->get_double();
359        if (constraint->apply_double(value, true) != Flag::SUCCESS) status = false;
360      }
361    }
362  }
363  return status;
364}
365