1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_LOGGING_LOGSTREAM_HPP
  26 #define SHARE_VM_LOGGING_LOGSTREAM_HPP
  27 
  28 #include "logging/log.hpp"
  29 #include "logging/logHandle.hpp"
  30 #include "memory/resourceArea.hpp"
  31 #include "utilities/ostream.hpp"
  32 
  33 
  34 
  35 
  36 // The base class of an output stream that logs to the logging framework.
  37 template <class streamClass>
  38 class LogStreamBase : public outputStream {
  39   streamClass     _current_line;
  40   LogTargetHandle _log_handle;
  41 
  42 public:
  43   // Constructor to support creation from a LogTarget instance.
  44   //
  45   // LogTarget(Debug, gc) log;
  46   // LogStreamBase(log) stream;
  47   template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
  48   LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
  49       _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
  50 
  51   // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
  52   //
  53   // LogStreamBase stream(log.debug());
  54   //  or
  55   // LogStreamBase stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
  56   template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
  57   LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>* type_carrier) :
  58       _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
  59 
  60   // Constructor to support creation from a LogTargetHandle.
  61   //
  62   // LogTarget(Debug, gc) log;
  63   // LogTargetHandle(log) handle;
  64   // LogStreamBase stream(handle);
  65   LogStreamBase(LogTargetHandle handle) : _log_handle(handle) {}
  66 
  67   // Constructor to support creation from a log level and tagset.
  68   //
  69   // LogStreamBase(level, tageset);
  70   LogStreamBase(LogLevelType level, LogTagSet* tagset) : _log_handle(level, tagset) {}
  71 
  72   ~LogStreamBase() {
  73     guarantee(_current_line.size() == 0, "Buffer not flushed. Missing call to print_cr()?");
  74   }
  75 
  76 public:
  77   void write(const char* s, size_t len);
  78 };
  79 
  80 // A stringStream with an embedded ResourceMark.
  81 class stringStreamWithResourceMark : outputStream {
  82  private:
  83   // The stringStream Resource allocate in the constructor,
  84   // so the order of the fields is important.
  85   ResourceMark _embedded_resource_mark;
  86   stringStream _stream;
  87 
  88  public:
  89   stringStreamWithResourceMark(size_t initial_bufsize = 256) :
  90       _embedded_resource_mark(),
  91       _stream(initial_bufsize) {}
  92 
  93   virtual void write(const char* c, size_t len) { _stream.write(c, len); }
  94   size_t      size()                            { return _stream.size(); }
  95   const char* base()                            { return _stream.base(); }
  96   void  reset()                                 { _stream.reset(); }
  97   char* as_string()                             { return _stream.as_string(); }
  98 };
  99 
 100 // An output stream that logs to the logging framework.
 101 //
 102 // The backing buffer is allocated in Resource memory.
 103 // The caller is required to have a ResourceMark on the stack.
 104 typedef LogStreamBase<stringStream> LogStreamNoResourceMark;
 105 
 106 // An output stream that logs to the logging framework.
 107 //
 108 // The backing buffer is allocated in CHeap memory.
 109 typedef LogStreamBase<bufferedStream> LogStreamCHeap;
 110 
 111 // An output stream that logs to the logging framework, and embeds a ResourceMark.
 112 //
 113 // The backing buffer is allocated in Resource memory.
 114 // The class is intended to be stack allocated.
 115 // The class provides its own ResourceMark,
 116 //  so care needs to be taken when nested ResourceMarks are used.
 117 typedef LogStreamBase<stringStreamWithResourceMark> LogStream;
 118 
 119 // Support creation of a LogStream without having to provide a LogTarget pointer.
 120 #define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
 121 
 122 template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
 123 class LogStreamTemplate : public LogStream {
 124 public:
 125   LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
 126 };
 127 
 128 
 129 #endif // SHARE_VM_LOGGING_LOGSTREAM_HPP