2012-02-14 14:14:51 +00:00
|
|
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
2014-04-29 06:42:26 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
#ifndef V8_COMPILER_H_
|
|
|
|
#define V8_COMPILER_H_
|
|
|
|
|
2014-06-03 08:12:43 +00:00
|
|
|
#include "src/allocation.h"
|
|
|
|
#include "src/ast.h"
|
2014-09-24 07:08:27 +00:00
|
|
|
#include "src/bailout-reason.h"
|
2015-04-20 15:22:02 +00:00
|
|
|
#include "src/compilation-dependencies.h"
|
2015-06-24 06:21:47 +00:00
|
|
|
#include "src/signature.h"
|
2014-06-03 08:12:43 +00:00
|
|
|
#include "src/zone.h"
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2009-05-25 10:05:56 +00:00
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2014-06-24 14:03:24 +00:00
|
|
|
class AstValueFactory;
|
2012-12-18 16:25:45 +00:00
|
|
|
class HydrogenCodeStub;
|
2015-07-06 11:11:15 +00:00
|
|
|
class JavaScriptFrame;
|
2015-03-09 14:51:13 +00:00
|
|
|
class ParseInfo;
|
|
|
|
class ScriptData;
|
2013-03-07 15:46:14 +00:00
|
|
|
|
2014-07-10 10:28:05 +00:00
|
|
|
|
2015-02-17 12:26:05 +00:00
|
|
|
// This class encapsulates encoding and decoding of sources positions from
|
|
|
|
// which hydrogen values originated.
|
|
|
|
// When FLAG_track_hydrogen_positions is set this object encodes the
|
|
|
|
// identifier of the inlining and absolute offset from the start of the
|
|
|
|
// inlined function.
|
|
|
|
// When the flag is not set we simply track absolute offset from the
|
|
|
|
// script start.
|
|
|
|
class SourcePosition {
|
|
|
|
public:
|
2015-02-27 13:34:23 +00:00
|
|
|
static SourcePosition Unknown() {
|
|
|
|
return SourcePosition::FromRaw(kNoPosition);
|
|
|
|
}
|
2015-02-17 12:26:05 +00:00
|
|
|
|
2015-02-18 07:33:20 +00:00
|
|
|
bool IsUnknown() const { return value_ == kNoPosition; }
|
2015-02-17 12:26:05 +00:00
|
|
|
|
2015-02-18 07:33:20 +00:00
|
|
|
uint32_t position() const { return PositionField::decode(value_); }
|
|
|
|
void set_position(uint32_t position) {
|
2015-02-17 12:26:05 +00:00
|
|
|
if (FLAG_hydrogen_track_positions) {
|
2015-02-18 07:33:20 +00:00
|
|
|
value_ = static_cast<uint32_t>(PositionField::update(value_, position));
|
2015-02-17 12:26:05 +00:00
|
|
|
} else {
|
|
|
|
value_ = position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-18 07:33:20 +00:00
|
|
|
uint32_t inlining_id() const { return InliningIdField::decode(value_); }
|
|
|
|
void set_inlining_id(uint32_t inlining_id) {
|
2015-02-17 12:26:05 +00:00
|
|
|
if (FLAG_hydrogen_track_positions) {
|
2015-02-18 07:33:20 +00:00
|
|
|
value_ =
|
|
|
|
static_cast<uint32_t>(InliningIdField::update(value_, inlining_id));
|
2015-02-17 12:26:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-18 07:33:20 +00:00
|
|
|
uint32_t raw() const { return value_; }
|
2015-02-17 12:26:05 +00:00
|
|
|
|
|
|
|
private:
|
2015-02-18 07:33:20 +00:00
|
|
|
static const uint32_t kNoPosition =
|
|
|
|
static_cast<uint32_t>(RelocInfo::kNoPosition);
|
|
|
|
typedef BitField<uint32_t, 0, 9> InliningIdField;
|
2015-02-17 12:26:05 +00:00
|
|
|
|
|
|
|
// Offset from the start of the inlined function.
|
2015-02-18 07:33:20 +00:00
|
|
|
typedef BitField<uint32_t, 9, 23> PositionField;
|
2015-02-17 12:26:05 +00:00
|
|
|
|
|
|
|
friend class HPositionInfo;
|
2015-02-27 13:34:23 +00:00
|
|
|
friend class Deoptimizer;
|
|
|
|
|
|
|
|
static SourcePosition FromRaw(uint32_t raw_position) {
|
|
|
|
SourcePosition position;
|
|
|
|
position.value_ = raw_position;
|
|
|
|
return position;
|
|
|
|
}
|
2015-02-17 12:26:05 +00:00
|
|
|
|
|
|
|
// If FLAG_hydrogen_track_positions is set contains bitfields InliningIdField
|
|
|
|
// and PositionField.
|
|
|
|
// Otherwise contains absolute offset from the script start.
|
2015-02-18 07:33:20 +00:00
|
|
|
uint32_t value_;
|
2015-02-17 12:26:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& os, const SourcePosition& p);
|
|
|
|
|
|
|
|
|
2015-03-11 13:51:18 +00:00
|
|
|
struct InlinedFunctionInfo {
|
|
|
|
InlinedFunctionInfo(int parent_id, SourcePosition inline_position,
|
|
|
|
int script_id, int start_position)
|
|
|
|
: parent_id(parent_id),
|
|
|
|
inline_position(inline_position),
|
|
|
|
script_id(script_id),
|
|
|
|
start_position(start_position) {}
|
|
|
|
int parent_id;
|
|
|
|
SourcePosition inline_position;
|
|
|
|
int script_id;
|
|
|
|
int start_position;
|
2015-03-24 12:46:13 +00:00
|
|
|
std::vector<size_t> deopt_pc_offsets;
|
2015-03-11 13:51:18 +00:00
|
|
|
|
|
|
|
static const int kNoParentId = -1;
|
2015-02-17 09:44:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-03 16:12:55 +00:00
|
|
|
// CompilationInfo encapsulates some information known at compile time. It
|
|
|
|
// is constructed based on the resources available at compile-time.
|
2012-07-19 18:58:23 +00:00
|
|
|
class CompilationInfo {
|
2010-01-29 11:55:40 +00:00
|
|
|
public:
|
2014-08-26 14:41:58 +00:00
|
|
|
// Various configuration flags for a compilation, as well as some properties
|
|
|
|
// of the compiled code produced by a compilation.
|
|
|
|
enum Flag {
|
2015-03-23 14:48:16 +00:00
|
|
|
kDeferredCalling = 1 << 0,
|
|
|
|
kNonDeferredCalling = 1 << 1,
|
|
|
|
kSavesCallerDoubles = 1 << 2,
|
|
|
|
kRequiresFrame = 1 << 3,
|
2015-03-23 19:11:19 +00:00
|
|
|
kMustNotHaveEagerFrame = 1 << 4,
|
|
|
|
kDeoptimizationSupport = 1 << 5,
|
|
|
|
kDebug = 1 << 6,
|
2015-07-20 14:53:28 +00:00
|
|
|
kSerializing = 1 << 7,
|
2015-09-25 11:33:28 +00:00
|
|
|
kFunctionContextSpecializing = 1 << 8,
|
2015-07-20 14:53:28 +00:00
|
|
|
kFrameSpecializing = 1 << 9,
|
2015-10-07 10:25:58 +00:00
|
|
|
kNativeContextSpecializing = 1 << 10,
|
|
|
|
kInliningEnabled = 1 << 11,
|
|
|
|
kTypingEnabled = 1 << 12,
|
|
|
|
kDisableFutureOptimization = 1 << 13,
|
|
|
|
kSplittingEnabled = 1 << 14,
|
|
|
|
kTypeFeedbackEnabled = 1 << 15,
|
|
|
|
kDeoptimizationEnabled = 1 << 16,
|
|
|
|
kSourcePositionsEnabled = 1 << 17,
|
|
|
|
kFirstCompile = 1 << 18,
|
2014-08-26 14:41:58 +00:00
|
|
|
};
|
|
|
|
|
2015-03-09 14:51:13 +00:00
|
|
|
explicit CompilationInfo(ParseInfo* parse_info);
|
2015-02-12 12:57:07 +00:00
|
|
|
CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone);
|
2015-08-28 12:46:12 +00:00
|
|
|
CompilationInfo(const char* debug_name, Isolate* isolate, Zone* zone);
|
2013-06-12 09:43:22 +00:00
|
|
|
virtual ~CompilationInfo();
|
2012-07-06 09:31:31 +00:00
|
|
|
|
2015-03-09 14:51:13 +00:00
|
|
|
ParseInfo* parse_info() const { return parse_info_; }
|
|
|
|
|
|
|
|
// -----------------------------------------------------------
|
|
|
|
// TODO(titzer): inline and delete accessors of ParseInfo
|
|
|
|
// -----------------------------------------------------------
|
|
|
|
Handle<Script> script() const;
|
|
|
|
bool is_eval() const;
|
|
|
|
bool is_native() const;
|
|
|
|
bool is_module() const;
|
|
|
|
LanguageMode language_mode() const;
|
|
|
|
Handle<JSFunction> closure() const;
|
2015-08-19 16:51:37 +00:00
|
|
|
FunctionLiteral* literal() const;
|
2015-03-09 14:51:13 +00:00
|
|
|
Scope* scope() const;
|
|
|
|
Handle<Context> context() const;
|
|
|
|
Handle<SharedFunctionInfo> shared_info() const;
|
|
|
|
bool has_shared_info() const;
|
2015-08-14 13:07:27 +00:00
|
|
|
bool has_context() const;
|
2015-08-19 16:51:37 +00:00
|
|
|
bool has_literal() const;
|
|
|
|
bool has_scope() const;
|
2015-03-09 14:51:13 +00:00
|
|
|
// -----------------------------------------------------------
|
|
|
|
|
2013-09-05 11:27:22 +00:00
|
|
|
Isolate* isolate() const {
|
2011-03-18 20:35:07 +00:00
|
|
|
return isolate_;
|
|
|
|
}
|
2013-09-09 16:34:40 +00:00
|
|
|
Zone* zone() { return zone_; }
|
|
|
|
bool is_osr() const { return !osr_ast_id_.IsNone(); }
|
2010-10-04 14:30:43 +00:00
|
|
|
Handle<Code> code() const { return code_; }
|
2015-02-10 11:45:59 +00:00
|
|
|
CodeStub* code_stub() const { return code_stub_; }
|
2012-08-06 14:13:09 +00:00
|
|
|
BailoutId osr_ast_id() const { return osr_ast_id_; }
|
2013-12-23 14:30:35 +00:00
|
|
|
Handle<Code> unoptimized_code() const { return unoptimized_code_; }
|
2013-01-23 13:52:00 +00:00
|
|
|
int opt_count() const { return opt_count_; }
|
2012-12-18 16:25:45 +00:00
|
|
|
int num_parameters() const;
|
2015-05-11 11:45:02 +00:00
|
|
|
int num_parameters_including_this() const;
|
|
|
|
bool is_this_defined() const;
|
2012-12-18 16:25:45 +00:00
|
|
|
int num_heap_slots() const;
|
2010-10-04 11:35:46 +00:00
|
|
|
|
2013-11-15 10:52:05 +00:00
|
|
|
void set_parameter_count(int parameter_count) {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK(IsStub());
|
2013-11-15 10:52:05 +00:00
|
|
|
parameter_count_ = parameter_count;
|
|
|
|
}
|
2014-01-14 12:04:10 +00:00
|
|
|
|
2015-03-16 14:17:01 +00:00
|
|
|
bool is_tracking_positions() const { return track_positions_; }
|
|
|
|
|
2012-12-18 16:25:45 +00:00
|
|
|
bool is_calling() const {
|
2014-08-26 14:41:58 +00:00
|
|
|
return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling);
|
2012-12-18 16:25:45 +00:00
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); }
|
2012-12-18 16:25:45 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
bool is_deferred_calling() const { return GetFlag(kDeferredCalling); }
|
2012-12-18 16:25:45 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); }
|
2012-12-18 16:25:45 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
bool is_non_deferred_calling() const { return GetFlag(kNonDeferredCalling); }
|
2012-12-18 16:25:45 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void MarkAsSavesCallerDoubles() { SetFlag(kSavesCallerDoubles); }
|
2013-02-04 12:01:59 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
bool saves_caller_doubles() const { return GetFlag(kSavesCallerDoubles); }
|
2013-02-04 12:01:59 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
|
2013-04-18 15:44:38 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
bool requires_frame() const { return GetFlag(kRequiresFrame); }
|
2013-04-18 15:44:38 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void MarkMustNotHaveEagerFrame() { SetFlag(kMustNotHaveEagerFrame); }
|
2014-05-12 07:49:11 +00:00
|
|
|
|
|
|
|
bool GetMustNotHaveEagerFrame() const {
|
2014-08-26 14:41:58 +00:00
|
|
|
return GetFlag(kMustNotHaveEagerFrame);
|
2014-05-12 07:49:11 +00:00
|
|
|
}
|
|
|
|
|
2015-07-20 14:53:28 +00:00
|
|
|
// Compiles marked as debug produce unoptimized code with debug break slots.
|
|
|
|
// Inner functions that cannot be compiled w/o context are compiled eagerly.
|
2015-07-24 13:43:38 +00:00
|
|
|
// Always include deoptimization support to avoid having to recompile again.
|
|
|
|
void MarkAsDebug() {
|
|
|
|
SetFlag(kDebug);
|
|
|
|
SetFlag(kDeoptimizationSupport);
|
|
|
|
}
|
2014-05-12 13:47:01 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
bool is_debug() const { return GetFlag(kDebug); }
|
2014-05-12 13:47:01 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void PrepareForSerializing() { SetFlag(kSerializing); }
|
2014-07-08 14:13:50 +00:00
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
bool will_serialize() const { return GetFlag(kSerializing); }
|
2014-07-08 14:13:50 +00:00
|
|
|
|
2015-09-25 11:33:28 +00:00
|
|
|
void MarkAsFunctionContextSpecializing() {
|
|
|
|
SetFlag(kFunctionContextSpecializing);
|
|
|
|
}
|
2014-08-26 15:17:57 +00:00
|
|
|
|
2015-09-25 11:33:28 +00:00
|
|
|
bool is_function_context_specializing() const {
|
|
|
|
return GetFlag(kFunctionContextSpecializing);
|
|
|
|
}
|
2014-08-26 15:17:57 +00:00
|
|
|
|
2015-07-06 11:11:15 +00:00
|
|
|
void MarkAsFrameSpecializing() { SetFlag(kFrameSpecializing); }
|
|
|
|
|
|
|
|
bool is_frame_specializing() const { return GetFlag(kFrameSpecializing); }
|
|
|
|
|
2015-10-07 10:25:58 +00:00
|
|
|
void MarkAsNativeContextSpecializing() {
|
|
|
|
SetFlag(kNativeContextSpecializing);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_native_context_specializing() const {
|
|
|
|
return GetFlag(kNativeContextSpecializing);
|
|
|
|
}
|
|
|
|
|
2015-03-26 09:38:11 +00:00
|
|
|
void MarkAsTypeFeedbackEnabled() { SetFlag(kTypeFeedbackEnabled); }
|
|
|
|
|
|
|
|
bool is_type_feedback_enabled() const {
|
|
|
|
return GetFlag(kTypeFeedbackEnabled);
|
|
|
|
}
|
|
|
|
|
2015-04-23 09:04:37 +00:00
|
|
|
void MarkAsDeoptimizationEnabled() { SetFlag(kDeoptimizationEnabled); }
|
|
|
|
|
|
|
|
bool is_deoptimization_enabled() const {
|
|
|
|
return GetFlag(kDeoptimizationEnabled);
|
|
|
|
}
|
|
|
|
|
2015-04-30 09:56:24 +00:00
|
|
|
void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
|
|
|
|
|
|
|
|
bool is_source_positions_enabled() const {
|
|
|
|
return GetFlag(kSourcePositionsEnabled);
|
|
|
|
}
|
|
|
|
|
2014-08-28 08:39:24 +00:00
|
|
|
void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
|
|
|
|
|
|
|
|
bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
|
|
|
|
|
2014-08-28 14:35:11 +00:00
|
|
|
void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); }
|
|
|
|
|
|
|
|
bool is_typing_enabled() const { return GetFlag(kTypingEnabled); }
|
|
|
|
|
2015-02-03 14:50:40 +00:00
|
|
|
void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
|
|
|
|
|
|
|
|
bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
|
|
|
|
|
2015-06-25 12:19:55 +00:00
|
|
|
void MarkAsFirstCompile() { SetFlag(kFirstCompile); }
|
|
|
|
|
2015-06-26 13:16:57 +00:00
|
|
|
void MarkAsCompiled() { SetFlag(kFirstCompile, false); }
|
|
|
|
|
2015-06-25 12:19:55 +00:00
|
|
|
bool is_first_compile() const { return GetFlag(kFirstCompile); }
|
|
|
|
|
2014-05-12 13:47:01 +00:00
|
|
|
bool IsCodePreAgingActive() const {
|
2014-07-08 14:13:50 +00:00
|
|
|
return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
|
|
|
|
!is_debug();
|
2014-05-12 13:47:01 +00:00
|
|
|
}
|
|
|
|
|
2014-11-14 08:21:13 +00:00
|
|
|
void EnsureFeedbackVector();
|
2014-09-18 09:59:53 +00:00
|
|
|
Handle<TypeFeedbackVector> feedback_vector() const {
|
2014-04-30 10:51:01 +00:00
|
|
|
return feedback_vector_;
|
|
|
|
}
|
2010-10-04 14:30:43 +00:00
|
|
|
void SetCode(Handle<Code> code) { code_ = code; }
|
2013-12-23 14:30:35 +00:00
|
|
|
|
2013-08-09 08:24:29 +00:00
|
|
|
bool ShouldTrapOnDeopt() const {
|
|
|
|
return (FLAG_trap_on_deopt && IsOptimizing()) ||
|
|
|
|
(FLAG_trap_on_stub_deopt && IsStub());
|
|
|
|
}
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
bool has_global_object() const {
|
2012-08-17 12:59:00 +00:00
|
|
|
return !closure().is_null() &&
|
|
|
|
(closure()->context()->global_object() != NULL);
|
2010-12-07 11:31:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GlobalObject* global_object() const {
|
2012-08-17 12:59:00 +00:00
|
|
|
return has_global_object() ? closure()->context()->global_object() : NULL;
|
2010-12-07 11:31:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Accessors for the different compilation modes.
|
|
|
|
bool IsOptimizing() const { return mode_ == OPTIMIZE; }
|
2012-12-18 16:25:45 +00:00
|
|
|
bool IsStub() const { return mode_ == STUB; }
|
2013-12-23 14:30:35 +00:00
|
|
|
void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) {
|
2015-09-18 11:03:30 +00:00
|
|
|
DCHECK(has_shared_info());
|
2010-12-07 11:31:57 +00:00
|
|
|
SetMode(OPTIMIZE);
|
|
|
|
osr_ast_id_ = osr_ast_id;
|
2013-12-23 14:30:35 +00:00
|
|
|
unoptimized_code_ = unoptimized;
|
2014-02-13 16:09:28 +00:00
|
|
|
optimization_id_ = isolate()->NextOptimizationId();
|
2015-09-23 14:00:23 +00:00
|
|
|
set_output_code_kind(Code::OPTIMIZED_FUNCTION);
|
2010-12-07 11:31:57 +00:00
|
|
|
}
|
|
|
|
|
2015-06-24 06:21:47 +00:00
|
|
|
void SetFunctionType(Type::FunctionType* function_type) {
|
|
|
|
function_type_ = function_type;
|
|
|
|
}
|
|
|
|
Type::FunctionType* function_type() const { return function_type_; }
|
|
|
|
|
2015-08-24 10:23:39 +00:00
|
|
|
void SetStub(CodeStub* code_stub);
|
2015-03-18 11:42:36 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
// Deoptimization support.
|
2011-10-18 13:40:33 +00:00
|
|
|
bool HasDeoptimizationSupport() const {
|
2014-08-26 14:41:58 +00:00
|
|
|
return GetFlag(kDeoptimizationSupport);
|
2011-10-18 13:40:33 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
void EnableDeoptimizationSupport() {
|
2015-08-21 15:21:08 +00:00
|
|
|
DCHECK_EQ(BASE, mode_);
|
2014-08-26 14:41:58 +00:00
|
|
|
SetFlag(kDeoptimizationSupport);
|
2010-12-07 11:31:57 +00:00
|
|
|
}
|
2015-08-24 10:23:39 +00:00
|
|
|
bool ShouldEnsureSpaceForLazyDeopt() { return !IsStub(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-08-27 20:31:25 +00:00
|
|
|
bool MustReplaceUndefinedReceiverWithGlobalProxy();
|
|
|
|
|
2014-11-21 17:28:18 +00:00
|
|
|
// Determines whether or not to insert a self-optimization header.
|
|
|
|
bool ShouldSelfOptimize();
|
|
|
|
|
2012-07-06 09:31:31 +00:00
|
|
|
void set_deferred_handles(DeferredHandles* deferred_handles) {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK(deferred_handles_ == NULL);
|
2012-07-06 09:31:31 +00:00
|
|
|
deferred_handles_ = deferred_handles;
|
|
|
|
}
|
|
|
|
|
2015-03-09 14:51:13 +00:00
|
|
|
void ReopenHandlesInNewHandleScope() {
|
|
|
|
unoptimized_code_ = Handle<Code>(*unoptimized_code_);
|
2012-07-19 18:58:23 +00:00
|
|
|
}
|
|
|
|
|
2014-09-24 07:08:27 +00:00
|
|
|
void AbortOptimization(BailoutReason reason) {
|
2015-01-13 14:36:50 +00:00
|
|
|
DCHECK(reason != kNoReason);
|
|
|
|
if (bailout_reason_ == kNoReason) bailout_reason_ = reason;
|
2014-09-24 07:08:27 +00:00
|
|
|
SetFlag(kDisableFutureOptimization);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RetryOptimization(BailoutReason reason) {
|
2015-01-13 14:36:50 +00:00
|
|
|
DCHECK(reason != kNoReason);
|
|
|
|
if (GetFlag(kDisableFutureOptimization)) return;
|
|
|
|
bailout_reason_ = reason;
|
2014-09-24 07:08:27 +00:00
|
|
|
}
|
|
|
|
|
2013-08-02 09:53:11 +00:00
|
|
|
BailoutReason bailout_reason() const { return bailout_reason_; }
|
2012-08-28 07:18:06 +00:00
|
|
|
|
2012-11-29 07:38:00 +00:00
|
|
|
int prologue_offset() const {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
|
2012-11-29 07:38:00 +00:00
|
|
|
return prologue_offset_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_prologue_offset(int prologue_offset) {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
|
2012-11-29 07:38:00 +00:00
|
|
|
prologue_offset_ = prologue_offset;
|
|
|
|
}
|
|
|
|
|
2015-03-19 12:39:43 +00:00
|
|
|
int start_position_for(uint32_t inlining_id) {
|
|
|
|
return inlined_function_infos_.at(inlining_id).start_position;
|
2015-03-18 09:30:29 +00:00
|
|
|
}
|
2015-03-24 12:46:13 +00:00
|
|
|
const std::vector<InlinedFunctionInfo>& inlined_function_infos() {
|
|
|
|
return inlined_function_infos_;
|
|
|
|
}
|
2015-03-18 09:30:29 +00:00
|
|
|
|
|
|
|
void LogDeoptCallPosition(int pc_offset, int inlining_id);
|
2015-02-17 12:26:05 +00:00
|
|
|
int TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
|
2015-03-11 13:51:18 +00:00
|
|
|
SourcePosition position, int pareint_id);
|
2015-02-17 09:44:44 +00:00
|
|
|
|
2015-04-20 15:22:02 +00:00
|
|
|
CompilationDependencies* dependencies() { return &dependencies_; }
|
2013-06-12 09:43:22 +00:00
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) {
|
2015-03-09 14:51:13 +00:00
|
|
|
return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure());
|
2013-09-04 12:55:59 +00:00
|
|
|
}
|
|
|
|
|
2014-02-13 16:09:28 +00:00
|
|
|
int optimization_id() const { return optimization_id_; }
|
|
|
|
|
2015-02-02 10:19:52 +00:00
|
|
|
int osr_expr_stack_height() { return osr_expr_stack_height_; }
|
|
|
|
void set_osr_expr_stack_height(int height) {
|
|
|
|
DCHECK(height >= 0);
|
|
|
|
osr_expr_stack_height_ = height;
|
|
|
|
}
|
2015-07-06 11:11:15 +00:00
|
|
|
JavaScriptFrame* osr_frame() const { return osr_frame_; }
|
|
|
|
void set_osr_frame(JavaScriptFrame* osr_frame) { osr_frame_ = osr_frame; }
|
2015-02-02 10:19:52 +00:00
|
|
|
|
2015-01-29 17:40:10 +00:00
|
|
|
#if DEBUG
|
|
|
|
void PrintAstForTesting();
|
|
|
|
#endif
|
|
|
|
|
2015-08-07 11:38:20 +00:00
|
|
|
bool has_simple_parameters();
|
2015-02-14 00:14:46 +00:00
|
|
|
|
2015-06-11 05:23:06 +00:00
|
|
|
typedef std::vector<Handle<SharedFunctionInfo>> InlinedFunctionList;
|
|
|
|
InlinedFunctionList const& inlined_functions() const {
|
|
|
|
return inlined_functions_;
|
|
|
|
}
|
|
|
|
void AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function) {
|
|
|
|
inlined_functions_.push_back(inlined_function);
|
|
|
|
}
|
|
|
|
|
2015-08-24 10:23:39 +00:00
|
|
|
base::SmartArrayPointer<char> GetDebugName() const;
|
|
|
|
|
2015-09-23 14:00:23 +00:00
|
|
|
Code::Kind output_code_kind() const { return output_code_kind_; }
|
|
|
|
|
|
|
|
void set_output_code_kind(Code::Kind kind) { output_code_kind_ = kind; }
|
|
|
|
|
2013-06-12 09:43:22 +00:00
|
|
|
protected:
|
2015-03-09 14:51:13 +00:00
|
|
|
ParseInfo* parse_info_;
|
2014-09-12 09:12:08 +00:00
|
|
|
|
2015-03-09 14:51:13 +00:00
|
|
|
void DisableFutureOptimization() {
|
|
|
|
if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
|
|
|
|
shared_info()->DisableOptimization(bailout_reason());
|
|
|
|
}
|
|
|
|
}
|
2013-05-14 22:51:33 +00:00
|
|
|
|
2010-10-04 11:35:46 +00:00
|
|
|
private:
|
2010-12-07 11:31:57 +00:00
|
|
|
// Compilation mode.
|
|
|
|
// BASE is generated by the full codegen, optionally prepared for bailouts.
|
|
|
|
// OPTIMIZE is optimized code generated by the Hydrogen-based backend.
|
|
|
|
enum Mode {
|
|
|
|
BASE,
|
|
|
|
OPTIMIZE,
|
2013-08-12 14:10:25 +00:00
|
|
|
STUB
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
2015-08-24 10:23:39 +00:00
|
|
|
CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub,
|
2015-08-28 12:46:12 +00:00
|
|
|
const char* debug_name, Mode mode, Isolate* isolate,
|
2015-08-24 10:23:39 +00:00
|
|
|
Zone* zone);
|
2015-03-19 12:39:43 +00:00
|
|
|
|
|
|
|
Isolate* isolate_;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
void SetMode(Mode mode) {
|
|
|
|
mode_ = mode;
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:58 +00:00
|
|
|
void SetFlag(Flag flag) { flags_ |= flag; }
|
|
|
|
|
|
|
|
void SetFlag(Flag flag, bool value) {
|
|
|
|
flags_ = value ? flags_ | flag : flags_ & ~flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
|
2010-10-04 11:35:46 +00:00
|
|
|
|
|
|
|
unsigned flags_;
|
|
|
|
|
2015-09-23 14:00:23 +00:00
|
|
|
Code::Kind output_code_kind_;
|
|
|
|
|
2012-12-18 16:25:45 +00:00
|
|
|
// For compiled stubs, the stub object
|
2015-02-10 11:45:59 +00:00
|
|
|
CodeStub* code_stub_;
|
2010-10-04 14:30:43 +00:00
|
|
|
// The compiled code.
|
|
|
|
Handle<Code> code_;
|
2010-09-30 08:48:37 +00:00
|
|
|
|
2014-04-30 10:51:01 +00:00
|
|
|
// Used by codegen, ultimately kept rooted by the SharedFunctionInfo.
|
2014-09-18 09:59:53 +00:00
|
|
|
Handle<TypeFeedbackVector> feedback_vector_;
|
2014-04-30 10:51:01 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
// Compilation mode flag and whether deoptimization is allowed.
|
|
|
|
Mode mode_;
|
2012-08-06 14:13:09 +00:00
|
|
|
BailoutId osr_ast_id_;
|
2013-12-05 16:17:44 +00:00
|
|
|
// The unoptimized code we patched for OSR may not be the shared code
|
|
|
|
// afterwards, since we may need to compile it again to include deoptimization
|
|
|
|
// data. Keep track which code we patched.
|
2013-12-23 14:30:35 +00:00
|
|
|
Handle<Code> unoptimized_code_;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-06-20 08:58:41 +00:00
|
|
|
// The zone from which the compilation pipeline working on this
|
|
|
|
// CompilationInfo allocates.
|
|
|
|
Zone* zone_;
|
|
|
|
|
2012-07-06 09:31:31 +00:00
|
|
|
DeferredHandles* deferred_handles_;
|
|
|
|
|
2015-04-20 15:22:02 +00:00
|
|
|
// Dependencies for this compilation, e.g. stable maps.
|
|
|
|
CompilationDependencies dependencies_;
|
2013-06-12 09:43:22 +00:00
|
|
|
|
2013-08-02 09:53:11 +00:00
|
|
|
BailoutReason bailout_reason_;
|
2012-08-28 07:18:06 +00:00
|
|
|
|
2012-11-29 07:38:00 +00:00
|
|
|
int prologue_offset_;
|
|
|
|
|
2015-03-19 12:39:43 +00:00
|
|
|
std::vector<InlinedFunctionInfo> inlined_function_infos_;
|
2015-03-16 14:17:01 +00:00
|
|
|
bool track_positions_;
|
2013-05-14 22:51:33 +00:00
|
|
|
|
2015-06-11 05:23:06 +00:00
|
|
|
InlinedFunctionList inlined_functions_;
|
|
|
|
|
2013-01-23 13:52:00 +00:00
|
|
|
// A copy of shared_info()->opt_count() to avoid handle deref
|
|
|
|
// during graph optimization.
|
|
|
|
int opt_count_;
|
|
|
|
|
2013-11-15 10:52:05 +00:00
|
|
|
// Number of parameters used for compilation of stubs that require arguments.
|
|
|
|
int parameter_count_;
|
|
|
|
|
2014-02-13 16:09:28 +00:00
|
|
|
int optimization_id_;
|
|
|
|
|
2015-02-02 10:19:52 +00:00
|
|
|
int osr_expr_stack_height_;
|
|
|
|
|
2015-07-06 11:11:15 +00:00
|
|
|
// The current OSR frame for specialization or {nullptr}.
|
|
|
|
JavaScriptFrame* osr_frame_ = nullptr;
|
|
|
|
|
2015-06-24 06:21:47 +00:00
|
|
|
Type::FunctionType* function_type_;
|
|
|
|
|
2015-08-28 12:46:12 +00:00
|
|
|
const char* debug_name_;
|
2015-08-24 10:23:39 +00:00
|
|
|
|
2010-10-04 11:35:46 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
|
2010-01-29 11:55:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-07-06 09:31:31 +00:00
|
|
|
// A wrapper around a CompilationInfo that detaches the Handles from
|
|
|
|
// the underlying DeferredHandleScope and stores them in info_ on
|
|
|
|
// destruction.
|
|
|
|
class CompilationHandleScope BASE_EMBEDDED {
|
|
|
|
public:
|
|
|
|
explicit CompilationHandleScope(CompilationInfo* info)
|
|
|
|
: deferred_(info->isolate()), info_(info) {}
|
|
|
|
~CompilationHandleScope() {
|
|
|
|
info_->set_deferred_handles(deferred_.Detach());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
DeferredHandleScope deferred_;
|
|
|
|
CompilationInfo* info_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-07-17 16:24:40 +00:00
|
|
|
class HGraph;
|
2012-12-18 16:25:45 +00:00
|
|
|
class HOptimizedGraphBuilder;
|
2012-07-17 16:24:40 +00:00
|
|
|
class LChunk;
|
|
|
|
|
|
|
|
// A helper class that calls the three compilation phases in
|
|
|
|
// Crankshaft and keeps track of its state. The three phases
|
|
|
|
// CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
|
|
|
|
// fail, bail-out to the full code generator or succeed. Apart from
|
|
|
|
// their return value, the status of the phase last run can be checked
|
|
|
|
// using last_status().
|
2013-12-23 14:30:35 +00:00
|
|
|
class OptimizedCompileJob: public ZoneObject {
|
2012-07-17 16:24:40 +00:00
|
|
|
public:
|
2013-12-23 14:30:35 +00:00
|
|
|
explicit OptimizedCompileJob(CompilationInfo* info)
|
2012-07-17 16:24:40 +00:00
|
|
|
: info_(info),
|
|
|
|
graph_builder_(NULL),
|
|
|
|
graph_(NULL),
|
|
|
|
chunk_(NULL),
|
2013-10-01 08:40:33 +00:00
|
|
|
last_status_(FAILED),
|
|
|
|
awaiting_install_(false) { }
|
2012-07-17 16:24:40 +00:00
|
|
|
|
|
|
|
enum Status {
|
|
|
|
FAILED, BAILED_OUT, SUCCEEDED
|
|
|
|
};
|
|
|
|
|
|
|
|
MUST_USE_RESULT Status CreateGraph();
|
|
|
|
MUST_USE_RESULT Status OptimizeGraph();
|
2013-12-23 14:30:35 +00:00
|
|
|
MUST_USE_RESULT Status GenerateCode();
|
2012-07-17 16:24:40 +00:00
|
|
|
|
|
|
|
Status last_status() const { return last_status_; }
|
|
|
|
CompilationInfo* info() const { return info_; }
|
2013-02-25 14:46:09 +00:00
|
|
|
Isolate* isolate() const { return info()->isolate(); }
|
2012-07-17 16:24:40 +00:00
|
|
|
|
2014-09-24 07:08:27 +00:00
|
|
|
Status RetryOptimization(BailoutReason reason) {
|
|
|
|
info_->RetryOptimization(reason);
|
2013-12-23 14:30:35 +00:00
|
|
|
return SetLastStatus(BAILED_OUT);
|
|
|
|
}
|
|
|
|
|
2014-09-24 07:08:27 +00:00
|
|
|
Status AbortOptimization(BailoutReason reason) {
|
|
|
|
info_->AbortOptimization(reason);
|
2012-07-19 18:58:23 +00:00
|
|
|
return SetLastStatus(BAILED_OUT);
|
|
|
|
}
|
|
|
|
|
2013-09-25 08:26:11 +00:00
|
|
|
void WaitForInstall() {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK(info_->is_osr());
|
2013-09-25 08:26:11 +00:00
|
|
|
awaiting_install_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsWaitingForInstall() { return awaiting_install_; }
|
|
|
|
|
2012-07-17 16:24:40 +00:00
|
|
|
private:
|
|
|
|
CompilationInfo* info_;
|
2012-12-18 16:25:45 +00:00
|
|
|
HOptimizedGraphBuilder* graph_builder_;
|
2012-07-17 16:24:40 +00:00
|
|
|
HGraph* graph_;
|
|
|
|
LChunk* chunk_;
|
2014-06-30 13:25:46 +00:00
|
|
|
base::TimeDelta time_taken_to_create_graph_;
|
|
|
|
base::TimeDelta time_taken_to_optimize_;
|
|
|
|
base::TimeDelta time_taken_to_codegen_;
|
2012-07-17 16:24:40 +00:00
|
|
|
Status last_status_;
|
2013-09-25 08:26:11 +00:00
|
|
|
bool awaiting_install_;
|
2012-07-17 16:24:40 +00:00
|
|
|
|
|
|
|
MUST_USE_RESULT Status SetLastStatus(Status status) {
|
|
|
|
last_status_ = status;
|
|
|
|
return last_status_;
|
|
|
|
}
|
|
|
|
void RecordOptimizationStats();
|
|
|
|
|
|
|
|
struct Timer {
|
2014-06-30 13:25:46 +00:00
|
|
|
Timer(OptimizedCompileJob* job, base::TimeDelta* location)
|
2013-09-25 10:01:18 +00:00
|
|
|
: job_(job), location_(location) {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK(location_ != NULL);
|
2013-08-29 09:15:13 +00:00
|
|
|
timer_.Start();
|
|
|
|
}
|
2012-07-17 16:24:40 +00:00
|
|
|
|
|
|
|
~Timer() {
|
2013-08-29 09:15:13 +00:00
|
|
|
*location_ += timer_.Elapsed();
|
2012-07-17 16:24:40 +00:00
|
|
|
}
|
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
OptimizedCompileJob* job_;
|
2014-06-30 13:25:46 +00:00
|
|
|
base::ElapsedTimer timer_;
|
|
|
|
base::TimeDelta* location_;
|
2012-07-17 16:24:40 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// The V8 compiler
|
|
|
|
//
|
|
|
|
// General strategy: Source code is translated into an anonymous function w/o
|
|
|
|
// parameters which then can be executed. If the source code contains other
|
|
|
|
// functions, they will be compiled and allocated as part of the compilation
|
|
|
|
// of the source code.
|
|
|
|
|
2010-10-04 14:30:43 +00:00
|
|
|
// Please note this interface returns shared function infos. This means you
|
|
|
|
// need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
|
|
|
|
// real function with a context.
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
class Compiler : public AllStatic {
|
|
|
|
public:
|
2014-04-22 14:55:47 +00:00
|
|
|
MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
|
|
|
|
Handle<JSFunction> function);
|
2014-09-17 15:29:42 +00:00
|
|
|
MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode(
|
|
|
|
Handle<JSFunction> function);
|
2015-08-24 06:52:46 +00:00
|
|
|
MUST_USE_RESULT static MaybeHandle<Code> GetStubCode(
|
|
|
|
Handle<JSFunction> function, CodeStub* stub);
|
2015-07-20 14:53:28 +00:00
|
|
|
|
2015-08-24 06:52:46 +00:00
|
|
|
static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag);
|
2015-07-27 13:15:06 +00:00
|
|
|
static bool CompileDebugCode(Handle<JSFunction> function);
|
|
|
|
static bool CompileDebugCode(Handle<SharedFunctionInfo> shared);
|
2015-08-24 06:52:46 +00:00
|
|
|
static void CompileForLiveEdit(Handle<Script> script);
|
2012-02-09 10:19:46 +00:00
|
|
|
|
2014-10-28 13:23:54 +00:00
|
|
|
// Parser::Parse, then Compiler::Analyze.
|
2015-03-09 14:51:13 +00:00
|
|
|
static bool ParseAndAnalyze(ParseInfo* info);
|
2014-10-28 13:23:54 +00:00
|
|
|
// Rewrite, analyze scopes, and renumber.
|
2015-03-09 14:51:13 +00:00
|
|
|
static bool Analyze(ParseInfo* info);
|
2014-10-28 13:23:54 +00:00
|
|
|
// Adds deoptimization support, requires ParseAndAnalyze.
|
|
|
|
static bool EnsureDeoptimizationSupport(CompilationInfo* info);
|
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
// Compile a String source within a context for eval.
|
2014-04-17 05:41:58 +00:00
|
|
|
MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
|
2014-10-28 10:00:37 +00:00
|
|
|
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
2015-02-04 09:34:05 +00:00
|
|
|
Handle<Context> context, LanguageMode language_mode,
|
2015-07-16 12:08:01 +00:00
|
|
|
ParseRestriction restriction, int line_offset, int column_offset = 0,
|
|
|
|
Handle<Object> script_name = Handle<Object>(),
|
|
|
|
ScriptOriginOptions options = ScriptOriginOptions());
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
// Compile a String source within a context.
|
2014-03-19 13:24:13 +00:00
|
|
|
static Handle<SharedFunctionInfo> CompileScript(
|
Change ScriptCompiler::CompileOptions to allow for two 'cache' modes
(parser or code) and to be explicit about cache consumption or production
(rather than making presence of cached_data imply one or the other.)
Also add a --cache flag to d8, to allow testing the functionality.
-----------------------------
API change
Reason: Currently, V8 supports a 'parser cache' for repeatedly executing the same script. We'd like to add a 2nd mode that would cache code, and would like to let the embedder decide which mode they chose (if any).
Note: Previously, the 'use cached data' property was implied by the presence of the cached data itself. (That is, kNoCompileOptions and source->cached_data != NULL.) That is no longer sufficient, since the presence of data is no longer sufficient to determine /which kind/ of data is present.
Changes from old behaviour:
- If you previously didn't use caching, nothing changes.
Example:
v8::CompileUnbound(isolate, source, kNoCompileOptions);
- If you previously used caching, it worked like this:
- 1st run:
v8::CompileUnbound(isolate, source, kProduceToCache);
Then, source->cached_data would contain the
data-to-be cached. This remains the same, except you
need to tell V8 which type of data you want.
v8::CompileUnbound(isolate, source, kProduceParserCache);
- 2nd run:
v8::CompileUnbound(isolate, source, kNoCompileOptions);
with source->cached_data set to the data you received in
the first run. This will now ignore the cached data, and
you need to explicitly tell V8 to use it:
v8::CompileUnbound(isolate, source, kConsumeParserCache);
-----------------------------
BUG=
R=marja@chromium.org, yangguo@chromium.org
Review URL: https://codereview.chromium.org/389573006
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22431 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-07-16 12:18:33 +00:00
|
|
|
Handle<String> source, Handle<Object> script_name, int line_offset,
|
2015-05-19 03:11:33 +00:00
|
|
|
int column_offset, ScriptOriginOptions resource_options,
|
2015-03-05 13:03:42 +00:00
|
|
|
Handle<Object> source_map_url, Handle<Context> context,
|
|
|
|
v8::Extension* extension, ScriptData** cached_data,
|
|
|
|
ScriptCompiler::CompileOptions compile_options,
|
2015-02-06 17:52:20 +00:00
|
|
|
NativesFlag is_natives_code, bool is_module);
|
2013-12-23 14:30:35 +00:00
|
|
|
|
2015-03-09 14:51:13 +00:00
|
|
|
static Handle<SharedFunctionInfo> CompileStreamedScript(Handle<Script> script,
|
|
|
|
ParseInfo* info,
|
2014-09-12 09:12:08 +00:00
|
|
|
int source_length);
|
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
// Create a shared function info object (the code may be lazily compiled).
|
2015-06-25 12:19:55 +00:00
|
|
|
static Handle<SharedFunctionInfo> GetSharedFunctionInfo(
|
|
|
|
FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer);
|
2009-11-04 17:59:24 +00:00
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
|
2010-02-04 15:35:42 +00:00
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
// Generate and return optimized code or start a concurrent optimization job.
|
|
|
|
// In the latter case, return the InOptimizationQueue builtin. On failure,
|
|
|
|
// return the empty handle.
|
2014-04-22 14:55:47 +00:00
|
|
|
MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode(
|
2015-07-06 11:11:15 +00:00
|
|
|
Handle<JSFunction> function, Handle<Code> current_code,
|
|
|
|
ConcurrencyMode mode, BailoutId osr_ast_id = BailoutId::None(),
|
|
|
|
JavaScriptFrame* osr_frame = nullptr);
|
2013-09-04 12:55:59 +00:00
|
|
|
|
2013-12-23 14:30:35 +00:00
|
|
|
// Generate and return code from previously queued optimization job.
|
|
|
|
// On failure, return the empty handle.
|
|
|
|
static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job);
|
2008-07-03 15:10:15 +00:00
|
|
|
};
|
|
|
|
|
2009-05-14 12:18:25 +00:00
|
|
|
|
2013-06-25 12:22:26 +00:00
|
|
|
class CompilationPhase BASE_EMBEDDED {
|
|
|
|
public:
|
2013-06-27 13:03:01 +00:00
|
|
|
CompilationPhase(const char* name, CompilationInfo* info);
|
2013-06-25 12:22:26 +00:00
|
|
|
~CompilationPhase();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool ShouldProduceTraceOutput() const;
|
|
|
|
|
|
|
|
const char* name() const { return name_; }
|
2013-06-27 13:09:08 +00:00
|
|
|
CompilationInfo* info() const { return info_; }
|
|
|
|
Isolate* isolate() const { return info()->isolate(); }
|
2013-06-27 13:03:01 +00:00
|
|
|
Zone* zone() { return &zone_; }
|
2013-06-25 12:22:26 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
const char* name_;
|
2013-06-27 13:03:01 +00:00
|
|
|
CompilationInfo* info_;
|
|
|
|
Zone zone_;
|
2015-02-12 12:46:58 +00:00
|
|
|
size_t info_zone_start_allocation_size_;
|
2014-06-30 13:25:46 +00:00
|
|
|
base::ElapsedTimer timer_;
|
2013-06-25 12:22:26 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CompilationPhase);
|
|
|
|
};
|
|
|
|
|
2015-09-30 13:46:56 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
#endif // V8_COMPILER_H_
|