blob: 4bbe6ae26b40262a3d5610942c90d95720cd4732 [file] [log] [blame]
Ben Murdoch8b112d22011-06-08 16:22:53 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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#include "v8.h"
29
30#include "bootstrapper.h"
Ben Murdoch8b112d22011-06-08 16:22:53 +010031#include "codegen.h"
Steve Blockd0582a62009-12-15 09:54:21 +000032#include "compiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000033#include "debug.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034#include "prettyprinter.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "rewriter.h"
36#include "runtime.h"
37#include "scopeinfo.h"
38#include "stub-cache.h"
39
40namespace v8 {
41namespace internal {
42
Andrei Popescu31002712010-02-23 13:46:05 +000043#define __ ACCESS_MASM(masm_)
44
45#ifdef DEBUG
46
47Comment::Comment(MacroAssembler* masm, const char* msg)
48 : masm_(masm), msg_(msg) {
49 __ RecordComment(msg);
50}
51
52
53Comment::~Comment() {
54 if (msg_[0] == '[') __ RecordComment("]");
55}
56
57#endif // DEBUG
58
59#undef __
60
Steve Blocka7e24c12009-10-30 11:49:00 +000061
Andrei Popescu31002712010-02-23 13:46:05 +000062void CodeGenerator::MakeCodePrologue(CompilationInfo* info) {
Steve Blocka7e24c12009-10-30 11:49:00 +000063#ifdef DEBUG
64 bool print_source = false;
65 bool print_ast = false;
Steve Block3ce2e202009-11-05 08:53:23 +000066 bool print_json_ast = false;
Steve Blocka7e24c12009-10-30 11:49:00 +000067 const char* ftype;
68
Steve Block44f0eee2011-05-26 01:26:41 +010069 if (Isolate::Current()->bootstrapper()->IsActive()) {
Steve Blocka7e24c12009-10-30 11:49:00 +000070 print_source = FLAG_print_builtin_source;
71 print_ast = FLAG_print_builtin_ast;
Steve Block3ce2e202009-11-05 08:53:23 +000072 print_json_ast = FLAG_print_builtin_json_ast;
Steve Blocka7e24c12009-10-30 11:49:00 +000073 ftype = "builtin";
74 } else {
75 print_source = FLAG_print_source;
76 print_ast = FLAG_print_ast;
Steve Block3ce2e202009-11-05 08:53:23 +000077 print_json_ast = FLAG_print_json_ast;
Ben Murdochb0fe1622011-05-05 13:52:32 +010078 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
79 if (print_source && !filter.is_empty()) {
80 print_source = info->function()->name()->IsEqualTo(filter);
81 }
82 if (print_ast && !filter.is_empty()) {
83 print_ast = info->function()->name()->IsEqualTo(filter);
84 }
85 if (print_json_ast && !filter.is_empty()) {
86 print_json_ast = info->function()->name()->IsEqualTo(filter);
87 }
Steve Blocka7e24c12009-10-30 11:49:00 +000088 ftype = "user-defined";
89 }
90
91 if (FLAG_trace_codegen || print_source || print_ast) {
92 PrintF("*** Generate code for %s function: ", ftype);
Andrei Popescu31002712010-02-23 13:46:05 +000093 info->function()->name()->ShortPrint();
Steve Blocka7e24c12009-10-30 11:49:00 +000094 PrintF(" ***\n");
95 }
96
97 if (print_source) {
Andrei Popescu31002712010-02-23 13:46:05 +000098 PrintF("--- Source from AST ---\n%s\n",
99 PrettyPrinter().PrintProgram(info->function()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000100 }
101
102 if (print_ast) {
Andrei Popescu31002712010-02-23 13:46:05 +0000103 PrintF("--- AST ---\n%s\n",
104 AstPrinter().PrintProgram(info->function()));
Steve Block3ce2e202009-11-05 08:53:23 +0000105 }
106
107 if (print_json_ast) {
108 JsonAstBuilder builder;
Andrei Popescu31002712010-02-23 13:46:05 +0000109 PrintF("%s", builder.BuildProgram(info->function()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000110 }
111#endif // DEBUG
Steve Block3ce2e202009-11-05 08:53:23 +0000112}
Steve Blocka7e24c12009-10-30 11:49:00 +0000113
Steve Blocka7e24c12009-10-30 11:49:00 +0000114
Andrei Popescu31002712010-02-23 13:46:05 +0000115Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
Steve Block3ce2e202009-11-05 08:53:23 +0000116 Code::Flags flags,
Andrei Popescu31002712010-02-23 13:46:05 +0000117 CompilationInfo* info) {
Steve Block44f0eee2011-05-26 01:26:41 +0100118 Isolate* isolate = info->isolate();
119
Steve Block3ce2e202009-11-05 08:53:23 +0000120 // Allocate and install the code.
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 CodeDesc desc;
Steve Block3ce2e202009-11-05 08:53:23 +0000122 masm->GetCode(&desc);
Steve Block44f0eee2011-05-26 01:26:41 +0100123 Handle<Code> code =
124 isolate->factory()->NewCode(desc, flags, masm->CodeObject());
Steve Blocka7e24c12009-10-30 11:49:00 +0000125
Ben Murdochb0fe1622011-05-05 13:52:32 +0100126 if (!code.is_null()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100127 isolate->counters()->total_compiled_code_size()->Increment(
128 code->instruction_size());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100129 }
130 return code;
131}
132
133
134void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000135#ifdef ENABLE_DISASSEMBLER
Steve Block44f0eee2011-05-26 01:26:41 +0100136 bool print_code = Isolate::Current()->bootstrapper()->IsActive()
Steve Block3ce2e202009-11-05 08:53:23 +0000137 ? FLAG_print_builtin_code
Ben Murdochb0fe1622011-05-05 13:52:32 +0100138 : (FLAG_print_code || (info->IsOptimizing() && FLAG_print_opt_code));
139 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
140 FunctionLiteral* function = info->function();
141 bool match = filter.is_empty() || function->debug_name()->IsEqualTo(filter);
142 if (print_code && match) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000143 // Print the source code if available.
Andrei Popescu31002712010-02-23 13:46:05 +0000144 Handle<Script> script = info->script();
Steve Blocka7e24c12009-10-30 11:49:00 +0000145 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
146 PrintF("--- Raw source ---\n");
147 StringInputBuffer stream(String::cast(script->source()));
Andrei Popescu31002712010-02-23 13:46:05 +0000148 stream.Seek(function->start_position());
Steve Block3ce2e202009-11-05 08:53:23 +0000149 // fun->end_position() points to the last character in the stream. We
Steve Blocka7e24c12009-10-30 11:49:00 +0000150 // need to compensate by adding one to calculate the length.
Andrei Popescu31002712010-02-23 13:46:05 +0000151 int source_len =
152 function->end_position() - function->start_position() + 1;
Steve Blocka7e24c12009-10-30 11:49:00 +0000153 for (int i = 0; i < source_len; i++) {
154 if (stream.has_more()) PrintF("%c", stream.GetNext());
155 }
156 PrintF("\n\n");
157 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100158 if (info->IsOptimizing()) {
159 if (FLAG_print_unopt_code) {
160 PrintF("--- Unoptimized code ---\n");
161 info->closure()->shared()->code()->Disassemble(
162 *function->debug_name()->ToCString());
163 }
164 PrintF("--- Optimized code ---\n");
165 } else {
166 PrintF("--- Code ---\n");
167 }
168 code->Disassemble(*function->debug_name()->ToCString());
Steve Blocka7e24c12009-10-30 11:49:00 +0000169 }
170#endif // ENABLE_DISASSEMBLER
Steve Blocka7e24c12009-10-30 11:49:00 +0000171}
172
Steve Blocka7e24c12009-10-30 11:49:00 +0000173#ifdef ENABLE_LOGGING_AND_PROFILING
174
Steve Block44f0eee2011-05-26 01:26:41 +0100175static Vector<const char> kRegexp = CStrVector("regexp");
176
Steve Blocka7e24c12009-10-30 11:49:00 +0000177bool CodeGenerator::ShouldGenerateLog(Expression* type) {
178 ASSERT(type != NULL);
Steve Block44f0eee2011-05-26 01:26:41 +0100179 if (!LOGGER->is_logging() && !CpuProfiler::is_profiling()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000180 Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
181 if (FLAG_log_regexp) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 if (name->IsEqualTo(kRegexp))
183 return true;
184 }
185 return false;
186}
187
188#endif
189
190
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100191bool CodeGenerator::RecordPositions(MacroAssembler* masm,
192 int pos,
193 bool right_here) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000194 if (pos != RelocInfo::kNoPosition) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800195 masm->positions_recorder()->RecordStatementPosition(pos);
196 masm->positions_recorder()->RecordPosition(pos);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100197 if (right_here) {
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800198 return masm->positions_recorder()->WriteRecordedPositions();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100199 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000200 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100201 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000202}
203
204
Leon Clarkee46be812010-01-19 14:06:41 +0000205const char* GenericUnaryOpStub::GetName() {
206 switch (op_) {
207 case Token::SUB:
Leon Clarkeac952652010-07-15 11:15:24 +0100208 if (negative_zero_ == kStrictNegativeZero) {
209 return overwrite_ == UNARY_OVERWRITE
210 ? "GenericUnaryOpStub_SUB_Overwrite_Strict0"
211 : "GenericUnaryOpStub_SUB_Alloc_Strict0";
212 } else {
213 return overwrite_ == UNARY_OVERWRITE
214 ? "GenericUnaryOpStub_SUB_Overwrite_Ignore0"
215 : "GenericUnaryOpStub_SUB_Alloc_Ignore0";
216 }
Leon Clarkee46be812010-01-19 14:06:41 +0000217 case Token::BIT_NOT:
Leon Clarkeac952652010-07-15 11:15:24 +0100218 return overwrite_ == UNARY_OVERWRITE
Leon Clarkee46be812010-01-19 14:06:41 +0000219 ? "GenericUnaryOpStub_BIT_NOT_Overwrite"
220 : "GenericUnaryOpStub_BIT_NOT_Alloc";
221 default:
222 UNREACHABLE();
223 return "<unknown>";
224 }
225}
226
227
Steve Blocka7e24c12009-10-30 11:49:00 +0000228void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
229 switch (type_) {
Steve Block44f0eee2011-05-26 01:26:41 +0100230 case READ_ELEMENT:
231 GenerateReadElement(masm);
232 break;
233 case NEW_NON_STRICT:
234 case NEW_STRICT:
235 GenerateNewObject(masm);
236 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000237 }
238}
239
240
Leon Clarke4515c472010-02-03 11:58:03 +0000241int CEntryStub::MinorKey() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100242 ASSERT(result_size_ == 1 || result_size_ == 2);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100243 int result = save_doubles_ ? 1 : 0;
Leon Clarke4515c472010-02-03 11:58:03 +0000244#ifdef _WIN64
Ben Murdochb0fe1622011-05-05 13:52:32 +0100245 return result | ((result_size_ == 1) ? 0 : 2);
Leon Clarke4515c472010-02-03 11:58:03 +0000246#else
Ben Murdochb0fe1622011-05-05 13:52:32 +0100247 return result;
Leon Clarke4515c472010-02-03 11:58:03 +0000248#endif
249}
250
251
Steve Blocka7e24c12009-10-30 11:49:00 +0000252} } // namespace v8::internal