bedf5eebb9469d59278bbb4d311f84c7ac7ac9d4
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / compiler.h
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_COMPILER_H_
29 #define V8_COMPILER_H_
30
31 #include "allocation.h"
32 #include "ast.h"
33 #include "zone.h"
34
35 namespace v8 {
36 namespace internal {
37
38 class ScriptDataImpl;
39
40 // CompilationInfo encapsulates some information known at compile time.  It
41 // is constructed based on the resources available at compile-time.
42 class CompilationInfo BASE_EMBEDDED {
43  public:
44   explicit CompilationInfo(Handle<Script> script);
45   explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info);
46   explicit CompilationInfo(Handle<JSFunction> closure);
47
48   Isolate* isolate() {
49     ASSERT(Isolate::Current() == isolate_);
50     return isolate_;
51   }
52   bool is_lazy() const { return IsLazy::decode(flags_); }
53   bool is_eval() const { return IsEval::decode(flags_); }
54   bool is_global() const { return IsGlobal::decode(flags_); }
55   bool is_strict_mode() const { return strict_mode_flag() == kStrictMode; }
56   StrictModeFlag strict_mode_flag() const {
57     return StrictModeFlagField::decode(flags_);
58   }
59   bool is_in_loop() const { return IsInLoop::decode(flags_); }
60   FunctionLiteral* function() const { return function_; }
61   Scope* scope() const { return scope_; }
62   Handle<Code> code() const { return code_; }
63   Handle<JSFunction> closure() const { return closure_; }
64   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
65   Handle<Script> script() const { return script_; }
66   v8::Extension* extension() const { return extension_; }
67   ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
68   Handle<Context> calling_context() const { return calling_context_; }
69   int osr_ast_id() const { return osr_ast_id_; }
70
71   void MarkAsEval() {
72     ASSERT(!is_lazy());
73     flags_ |= IsEval::encode(true);
74   }
75   void MarkAsGlobal() {
76     ASSERT(!is_lazy());
77     flags_ |= IsGlobal::encode(true);
78   }
79   void SetStrictModeFlag(StrictModeFlag strict_mode_flag) {
80     ASSERT(StrictModeFlagField::decode(flags_) == kNonStrictMode ||
81            StrictModeFlagField::decode(flags_) == strict_mode_flag);
82     flags_ = StrictModeFlagField::update(flags_, strict_mode_flag);
83   }
84   void MarkAsInLoop() {
85     ASSERT(is_lazy());
86     flags_ |= IsInLoop::encode(true);
87   }
88   void MarkAsNative() {
89     flags_ |= IsNative::encode(true);
90   }
91   bool is_native() const {
92     return IsNative::decode(flags_);
93   }
94   void SetFunction(FunctionLiteral* literal) {
95     ASSERT(function_ == NULL);
96     function_ = literal;
97   }
98   void SetScope(Scope* scope) {
99     ASSERT(scope_ == NULL);
100     scope_ = scope;
101   }
102   void SetCode(Handle<Code> code) { code_ = code; }
103   void SetExtension(v8::Extension* extension) {
104     ASSERT(!is_lazy());
105     extension_ = extension;
106   }
107   void SetPreParseData(ScriptDataImpl* pre_parse_data) {
108     ASSERT(!is_lazy());
109     pre_parse_data_ = pre_parse_data;
110   }
111   void SetCallingContext(Handle<Context> context) {
112     ASSERT(is_eval());
113     calling_context_ = context;
114   }
115   void SetOsrAstId(int osr_ast_id) {
116     ASSERT(IsOptimizing());
117     osr_ast_id_ = osr_ast_id;
118   }
119   void MarkCompilingForDebugging(Handle<Code> current_code) {
120     ASSERT(mode_ != OPTIMIZE);
121     ASSERT(current_code->kind() == Code::FUNCTION);
122     flags_ |= IsCompilingForDebugging::encode(true);
123     if (current_code->is_compiled_optimizable()) {
124       EnableDeoptimizationSupport();
125     } else {
126       mode_ = CompilationInfo::NONOPT;
127     }
128   }
129   bool IsCompilingForDebugging() {
130     return IsCompilingForDebugging::decode(flags_);
131   }
132
133   bool has_global_object() const {
134     return !closure().is_null() && (closure()->context()->global() != NULL);
135   }
136
137   GlobalObject* global_object() const {
138     return has_global_object() ? closure()->context()->global() : NULL;
139   }
140
141   // Accessors for the different compilation modes.
142   bool IsOptimizing() const { return mode_ == OPTIMIZE; }
143   bool IsOptimizable() const { return mode_ == BASE; }
144   void SetOptimizing(int osr_ast_id) {
145     SetMode(OPTIMIZE);
146     osr_ast_id_ = osr_ast_id;
147   }
148   void DisableOptimization();
149
150   // Deoptimization support.
151   bool HasDeoptimizationSupport() const {
152     return SupportsDeoptimization::decode(flags_);
153   }
154   void EnableDeoptimizationSupport() {
155     ASSERT(IsOptimizable());
156     flags_ |= SupportsDeoptimization::encode(true);
157   }
158
159   // Determine whether or not we can adaptively optimize.
160   bool AllowOptimize() {
161     return V8::UseCrankshaft() && !closure_.is_null();
162   }
163
164   // Disable all optimization attempts of this info for the rest of the
165   // current compilation pipeline.
166   void AbortOptimization();
167
168  private:
169   Isolate* isolate_;
170
171   // Compilation mode.
172   // BASE is generated by the full codegen, optionally prepared for bailouts.
173   // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
174   // NONOPT is generated by the full codegen or the classic backend
175   //   and is not prepared for recompilation/bailouts. These functions
176   //   are never recompiled.
177   enum Mode {
178     BASE,
179     OPTIMIZE,
180     NONOPT
181   };
182
183   CompilationInfo() : function_(NULL) {}
184
185   void Initialize(Mode mode) {
186     mode_ = V8::UseCrankshaft() ? mode : NONOPT;
187     ASSERT(!script_.is_null());
188     if (script_->type()->value() == Script::TYPE_NATIVE) {
189       MarkAsNative();
190     }
191     if (!shared_info_.is_null()) {
192       ASSERT(strict_mode_flag() == kNonStrictMode);
193       SetStrictModeFlag(shared_info_->strict_mode_flag());
194     }
195   }
196
197   void SetMode(Mode mode) {
198     ASSERT(V8::UseCrankshaft());
199     mode_ = mode;
200   }
201
202   // Flags using template class BitField<type, start, length>.  All are
203   // false by default.
204   //
205   // Compilation is either eager or lazy.
206   class IsLazy:   public BitField<bool, 0, 1> {};
207   // Flags that can be set for eager compilation.
208   class IsEval:   public BitField<bool, 1, 1> {};
209   class IsGlobal: public BitField<bool, 2, 1> {};
210   // Flags that can be set for lazy compilation.
211   class IsInLoop: public BitField<bool, 3, 1> {};
212   // Strict mode - used in eager compilation.
213   class StrictModeFlagField: public BitField<StrictModeFlag, 4, 1> {};
214   // Is this a function from our natives.
215   class IsNative: public BitField<bool, 6, 1> {};
216   // Is this code being compiled with support for deoptimization..
217   class SupportsDeoptimization: public BitField<bool, 7, 1> {};
218   // If compiling for debugging produce just full code matching the
219   // initial mode setting.
220   class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
221
222
223   unsigned flags_;
224
225   // Fields filled in by the compilation pipeline.
226   // AST filled in by the parser.
227   FunctionLiteral* function_;
228   // The scope of the function literal as a convenience.  Set to indicate
229   // that scopes have been analyzed.
230   Scope* scope_;
231   // The compiled code.
232   Handle<Code> code_;
233
234   // Possible initial inputs to the compilation process.
235   Handle<JSFunction> closure_;
236   Handle<SharedFunctionInfo> shared_info_;
237   Handle<Script> script_;
238
239   // Fields possibly needed for eager compilation, NULL by default.
240   v8::Extension* extension_;
241   ScriptDataImpl* pre_parse_data_;
242
243   // The context of the caller is needed for eval code, and will be a null
244   // handle otherwise.
245   Handle<Context> calling_context_;
246
247   // Compilation mode flag and whether deoptimization is allowed.
248   Mode mode_;
249   int osr_ast_id_;
250
251   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
252 };
253
254
255 // The V8 compiler
256 //
257 // General strategy: Source code is translated into an anonymous function w/o
258 // parameters which then can be executed. If the source code contains other
259 // functions, they will be compiled and allocated as part of the compilation
260 // of the source code.
261
262 // Please note this interface returns shared function infos.  This means you
263 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
264 // real function with a context.
265
266 class Compiler : public AllStatic {
267  public:
268   // Default maximum number of function optimization attempts before we
269   // give up.
270   static const int kDefaultMaxOptCount = 10;
271
272   static const int kMaxInliningLevels = 3;
273
274   // All routines return a SharedFunctionInfo.
275   // If an error occurs an exception is raised and the return handle
276   // contains NULL.
277
278   // Compile a String source within a context.
279   static Handle<SharedFunctionInfo> Compile(Handle<String> source,
280                                             Handle<Object> script_name,
281                                             int line_offset,
282                                             int column_offset,
283                                             v8::Extension* extension,
284                                             ScriptDataImpl* pre_data,
285                                             Handle<Object> script_data,
286                                             NativesFlag is_natives_code);
287
288   // Compile a String source within a context for Eval.
289   static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
290                                                 Handle<Context> context,
291                                                 bool is_global,
292                                                 StrictModeFlag strict_mode);
293
294   // Compile from function info (used for lazy compilation). Returns true on
295   // success and false if the compilation resulted in a stack overflow.
296   static bool CompileLazy(CompilationInfo* info);
297
298   // Compile a shared function info object (the function is possibly lazily
299   // compiled).
300   static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
301                                                       Handle<Script> script);
302
303   // Set the function info for a newly compiled function.
304   static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
305                               FunctionLiteral* lit,
306                               bool is_toplevel,
307                               Handle<Script> script);
308
309 #ifdef ENABLE_DEBUGGER_SUPPORT
310   static bool MakeCodeForLiveEdit(CompilationInfo* info);
311 #endif
312
313   static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
314                                         CompilationInfo* info,
315                                         Handle<SharedFunctionInfo> shared);
316 };
317
318
319 } }  // namespace v8::internal
320
321 #endif  // V8_COMPILER_H_