blob: f9a2453a09559b7ec5a2c2c32840606ae48718c8 [file] [log] [blame]
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00001// Copyright 2010 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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
ager@chromium.org7c537e22008-10-16 08:43:32 +000030#include "bootstrapper.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031#include "codegen-inl.h"
ager@chromium.orgc4c92722009-11-18 14:12:51 +000032#include "compiler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000033#include "debug.h"
ager@chromium.org71daaf62009-04-01 07:22:49 +000034#include "oprofile-agent.h"
ager@chromium.org7c537e22008-10-16 08:43:32 +000035#include "prettyprinter.h"
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000036#include "register-allocator-inl.h"
ager@chromium.org71daaf62009-04-01 07:22:49 +000037#include "rewriter.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038#include "runtime.h"
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000039#include "scopeinfo.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "stub-cache.h"
sgjesse@chromium.org833cdd72010-02-26 10:06:16 +000041#include "virtual-frame-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
ager@chromium.org5c838252010-02-19 08:53:10 +000046#define __ ACCESS_MASM(masm_)
47
48#ifdef DEBUG
49
50Comment::Comment(MacroAssembler* masm, const char* msg)
51 : masm_(masm), msg_(msg) {
52 __ RecordComment(msg);
53}
54
55
56Comment::~Comment() {
57 if (msg_[0] == '[') __ RecordComment("]");
58}
59
60#endif // DEBUG
61
62#undef __
63
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +000064
65CodeGenerator* CodeGeneratorScope::top_ = NULL;
66
67
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068void CodeGenerator::ProcessDeferred() {
69 while (!deferred_.is_empty()) {
70 DeferredCode* code = deferred_.RemoveLast();
ager@chromium.orge2902be2009-06-08 12:21:35 +000071 ASSERT(masm_ == code->masm());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072 // Record position of deferred code stub.
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +000073 masm_->positions_recorder()->RecordStatementPosition(
74 code->statement_position());
ager@chromium.org236ad962008-09-25 09:45:57 +000075 if (code->position() != RelocInfo::kNoPosition) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +000076 masm_->positions_recorder()->RecordPosition(code->position());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077 }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +000078 // Generate the code.
ager@chromium.orge2902be2009-06-08 12:21:35 +000079 Comment cmnt(masm_, code->comment());
80 masm_->bind(code->entry_label());
vegorov@chromium.org26c16f82010-08-11 13:41:03 +000081 if (code->AutoSaveAndRestore()) {
82 code->SaveRegisters();
83 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084 code->Generate();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +000085 if (code->AutoSaveAndRestore()) {
86 code->RestoreRegisters();
87 code->Exit();
88 }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +000089 }
90}
91
92
vegorov@chromium.org26c16f82010-08-11 13:41:03 +000093void DeferredCode::Exit() {
94 masm_->jmp(exit_label());
95}
96
97
kasperl@chromium.org7be3c992009-03-12 07:19:55 +000098void CodeGenerator::SetFrame(VirtualFrame* new_frame,
99 RegisterFile* non_frame_registers) {
100 RegisterFile saved_counts;
101 if (has_valid_frame()) {
102 frame_->DetachFromCodeGenerator();
103 // The remaining register reference counts are the non-frame ones.
104 allocator_->SaveTo(&saved_counts);
105 }
106
107 if (new_frame != NULL) {
108 // Restore the non-frame register references that go with the new frame.
109 allocator_->RestoreFrom(non_frame_registers);
110 new_frame->AttachToCodeGenerator();
111 }
112
113 frame_ = new_frame;
114 saved_counts.CopyTo(non_frame_registers);
115}
116
117
118void CodeGenerator::DeleteFrame() {
119 if (has_valid_frame()) {
120 frame_->DetachFromCodeGenerator();
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000121 frame_ = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000122 }
123}
124
125
ager@chromium.org5c838252010-02-19 08:53:10 +0000126void CodeGenerator::MakeCodePrologue(CompilationInfo* info) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000127#ifdef DEBUG
128 bool print_source = false;
129 bool print_ast = false;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000130 bool print_json_ast = false;
ager@chromium.org7c537e22008-10-16 08:43:32 +0000131 const char* ftype;
132
133 if (Bootstrapper::IsActive()) {
134 print_source = FLAG_print_builtin_source;
135 print_ast = FLAG_print_builtin_ast;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000136 print_json_ast = FLAG_print_builtin_json_ast;
ager@chromium.org7c537e22008-10-16 08:43:32 +0000137 ftype = "builtin";
138 } else {
139 print_source = FLAG_print_source;
140 print_ast = FLAG_print_ast;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000141 print_json_ast = FLAG_print_json_ast;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000142 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
143 if (print_source && !filter.is_empty()) {
144 print_source = info->function()->name()->IsEqualTo(filter);
145 }
146 if (print_ast && !filter.is_empty()) {
147 print_ast = info->function()->name()->IsEqualTo(filter);
148 }
149 if (print_json_ast && !filter.is_empty()) {
150 print_json_ast = info->function()->name()->IsEqualTo(filter);
151 }
ager@chromium.org7c537e22008-10-16 08:43:32 +0000152 ftype = "user-defined";
153 }
154
155 if (FLAG_trace_codegen || print_source || print_ast) {
156 PrintF("*** Generate code for %s function: ", ftype);
ager@chromium.org5c838252010-02-19 08:53:10 +0000157 info->function()->name()->ShortPrint();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000158 PrintF(" ***\n");
159 }
160
161 if (print_source) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000162 PrintF("--- Source from AST ---\n%s\n",
163 PrettyPrinter().PrintProgram(info->function()));
ager@chromium.org7c537e22008-10-16 08:43:32 +0000164 }
165
166 if (print_ast) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000167 PrintF("--- AST ---\n%s\n",
168 AstPrinter().PrintProgram(info->function()));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000169 }
170
171 if (print_json_ast) {
172 JsonAstBuilder builder;
ager@chromium.org5c838252010-02-19 08:53:10 +0000173 PrintF("%s", builder.BuildProgram(info->function()));
ager@chromium.org7c537e22008-10-16 08:43:32 +0000174 }
175#endif // DEBUG
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000176}
ager@chromium.org7c537e22008-10-16 08:43:32 +0000177
ager@chromium.org7c537e22008-10-16 08:43:32 +0000178
ager@chromium.org5c838252010-02-19 08:53:10 +0000179Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000180 Code::Flags flags,
ager@chromium.org5c838252010-02-19 08:53:10 +0000181 CompilationInfo* info) {
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000182 // Allocate and install the code.
ager@chromium.org7c537e22008-10-16 08:43:32 +0000183 CodeDesc desc;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000184 masm->GetCode(&desc);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000185 Handle<Code> code = Factory::NewCode(desc, flags, masm->CodeObject());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000186
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000187 if (!code.is_null()) {
188 Counters::total_compiled_code_size.Increment(code->instruction_size());
189 }
190 return code;
191}
192
193
194void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000195#ifdef ENABLE_DISASSEMBLER
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000196 bool print_code = Bootstrapper::IsActive()
197 ? FLAG_print_builtin_code
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198 : (FLAG_print_code || (info->IsOptimizing() && FLAG_print_opt_code));
199 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
200 FunctionLiteral* function = info->function();
201 bool match = filter.is_empty() || function->debug_name()->IsEqualTo(filter);
202 if (print_code && match) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000203 // Print the source code if available.
ager@chromium.org5c838252010-02-19 08:53:10 +0000204 Handle<Script> script = info->script();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000205 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
206 PrintF("--- Raw source ---\n");
207 StringInputBuffer stream(String::cast(script->source()));
ager@chromium.org5c838252010-02-19 08:53:10 +0000208 stream.Seek(function->start_position());
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000209 // fun->end_position() points to the last character in the stream. We
ager@chromium.org7c537e22008-10-16 08:43:32 +0000210 // need to compensate by adding one to calculate the length.
ager@chromium.org5c838252010-02-19 08:53:10 +0000211 int source_len =
212 function->end_position() - function->start_position() + 1;
ager@chromium.org7c537e22008-10-16 08:43:32 +0000213 for (int i = 0; i < source_len; i++) {
214 if (stream.has_more()) PrintF("%c", stream.GetNext());
215 }
216 PrintF("\n\n");
217 }
whesse@chromium.org023421e2010-12-21 12:19:12 +0000218 if (info->IsOptimizing()) {
219 if (FLAG_print_unopt_code) {
220 PrintF("--- Unoptimized code ---\n");
221 info->closure()->shared()->code()->Disassemble(
222 *function->debug_name()->ToCString());
223 }
224 PrintF("--- Optimized code ---\n");
225 } else {
226 PrintF("--- Code ---\n");
227 }
228 code->Disassemble(*function->debug_name()->ToCString());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000229 }
230#endif // ENABLE_DISASSEMBLER
ager@chromium.org7c537e22008-10-16 08:43:32 +0000231}
232
233
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000234// Generate the code. Compile the AST and assemble all the pieces into a
235// Code object.
236bool CodeGenerator::MakeCode(CompilationInfo* info) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237 // When using Crankshaft the classic backend should never be used.
238 ASSERT(!V8::UseCrankshaft());
ager@chromium.org5c838252010-02-19 08:53:10 +0000239 Handle<Script> script = info->script();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000240 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
241 int len = String::cast(script->source())->length();
242 Counters::total_old_codegen_source_size.Increment(len);
243 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244 if (FLAG_trace_codegen) {
245 PrintF("Classic Compiler - ");
246 }
ager@chromium.org5c838252010-02-19 08:53:10 +0000247 MakeCodePrologue(info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000248 // Generate code.
249 const int kInitialBufferSize = 4 * KB;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000250 MacroAssembler masm(NULL, kInitialBufferSize);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000251#ifdef ENABLE_GDB_JIT_INTERFACE
252 masm.positions_recorder()->StartGDBJITLineInfoRecording();
253#endif
ager@chromium.org5c838252010-02-19 08:53:10 +0000254 CodeGenerator cgen(&masm);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000255 CodeGeneratorScope scope(&cgen);
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +0000256 cgen.Generate(info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000257 if (cgen.HasStackOverflow()) {
258 ASSERT(!Top::has_pending_exception());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000259 return false;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000260 }
261
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000262 InLoopFlag in_loop = info->is_in_loop() ? IN_LOOP : NOT_IN_LOOP;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000263 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000264 Handle<Code> code = MakeCodeEpilogue(cgen.masm(), flags, info);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000265 // There is no stack check table in code generated by the classic backend.
266 code->SetNoStackCheckTable();
267 CodeGenerator::PrintCode(code, info);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000268 info->SetCode(code); // May be an empty handle.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000269#ifdef ENABLE_GDB_JIT_INTERFACE
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000270 if (FLAG_gdbjit && !code.is_null()) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000271 GDBJITLineInfo* lineinfo =
272 masm.positions_recorder()->DetachGDBJITLineInfo();
273
274 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
275 }
276#endif
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000277 return !code.is_null();
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000278}
279
280
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +0000281#ifdef ENABLE_LOGGING_AND_PROFILING
282
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000283bool CodeGenerator::ShouldGenerateLog(Expression* type) {
284 ASSERT(type != NULL);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000285 if (!Logger::is_logging() && !CpuProfiler::is_profiling()) return false;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000286 Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
287 if (FLAG_log_regexp) {
288 static Vector<const char> kRegexp = CStrVector("regexp");
289 if (name->IsEqualTo(kRegexp))
290 return true;
291 }
292 return false;
293}
294
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +0000295#endif
296
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000298void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) {
299 int length = declarations->length();
300 int globals = 0;
301 for (int i = 0; i < length; i++) {
302 Declaration* node = declarations->at(i);
303 Variable* var = node->proxy()->var();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000304 Slot* slot = var->AsSlot();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000305
306 // If it was not possible to allocate the variable at compile
307 // time, we need to "declare" it at runtime to make sure it
308 // actually exists in the local context.
309 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
310 VisitDeclaration(node);
311 } else {
312 // Count global variables and functions for later processing
313 globals++;
314 }
315 }
316
317 // Return in case of no declared global functions or variables.
318 if (globals == 0) return;
319
320 // Compute array of global variable and function declarations.
321 Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED);
322 for (int j = 0, i = 0; i < length; i++) {
323 Declaration* node = declarations->at(i);
324 Variable* var = node->proxy()->var();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000325 Slot* slot = var->AsSlot();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000326
327 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
328 // Skip - already processed.
329 } else {
330 array->set(j++, *(var->name()));
331 if (node->fun() == NULL) {
332 if (var->mode() == Variable::CONST) {
333 // In case this is const property use the hole.
334 array->set_the_hole(j++);
335 } else {
336 array->set_undefined(j++);
337 }
338 } else {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000339 Handle<SharedFunctionInfo> function =
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000340 Compiler::BuildFunctionInfo(node->fun(), script());
kasper.lund212ac232008-07-16 07:07:30 +0000341 // Check for stack-overflow exception.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000342 if (function.is_null()) {
343 SetStackOverflow();
344 return;
345 }
kasper.lund212ac232008-07-16 07:07:30 +0000346 array->set(j++, *function);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000347 }
348 }
349 }
350
351 // Invoke the platform-dependent code generator to do the actual
352 // declaration the global variables and functions.
353 DeclareGlobals(array);
354}
355
356
ricow@chromium.org65fae842010-08-25 15:26:24 +0000357void CodeGenerator::VisitIncrementOperation(IncrementOperation* expr) {
358 UNREACHABLE();
359}
360
361
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000362// Lookup table for code generators for special runtime calls which are
363// generated inline.
364#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
365 &CodeGenerator::Generate##Name,
ager@chromium.org9085a012009-05-11 19:22:57 +0000366
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000367const CodeGenerator::InlineFunctionGenerator
368 CodeGenerator::kInlineFunctionGenerators[] = {
369 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
370 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000371};
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000372#undef INLINE_FUNCTION_GENERATOR_ADDRESS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000373
374
375bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
376 ZoneList<Expression*>* args = node->arguments();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000377 Handle<String> name = node->name();
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000378 Runtime::Function* function = node->function();
379 if (function != NULL && function->intrinsic_type == Runtime::INLINE) {
vegorov@chromium.org42841962010-10-18 11:18:59 +0000380 int lookup_index = static_cast<int>(function->function_id) -
381 static_cast<int>(Runtime::kFirstInlineFunction);
382 ASSERT(lookup_index >= 0);
383 ASSERT(static_cast<size_t>(lookup_index) <
384 ARRAY_SIZE(kInlineFunctionGenerators));
385 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
386 (this->*generator)(args);
387 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000388 }
389 return false;
390}
391
392
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000393// Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
394// known result for the test expression, with no side effects.
395CodeGenerator::ConditionAnalysis CodeGenerator::AnalyzeCondition(
396 Expression* cond) {
397 if (cond == NULL) return ALWAYS_TRUE;
398
399 Literal* lit = cond->AsLiteral();
400 if (lit == NULL) return DONT_KNOW;
401
402 if (lit->IsTrue()) {
403 return ALWAYS_TRUE;
404 } else if (lit->IsFalse()) {
405 return ALWAYS_FALSE;
406 }
407
408 return DONT_KNOW;
409}
410
411
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000412bool CodeGenerator::RecordPositions(MacroAssembler* masm,
413 int pos,
414 bool right_here) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000415 if (pos != RelocInfo::kNoPosition) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +0000416 masm->positions_recorder()->RecordStatementPosition(pos);
417 masm->positions_recorder()->RecordPosition(pos);
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000418 if (right_here) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +0000419 return masm->positions_recorder()->WriteRecordedPositions();
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000420 }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000421 }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000422 return false;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000423}
424
425
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000426void CodeGenerator::CodeForFunctionPosition(FunctionLiteral* fun) {
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000427 if (FLAG_debug_info) RecordPositions(masm(), fun->start_position(), false);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000428}
429
430
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000431void CodeGenerator::CodeForReturnPosition(FunctionLiteral* fun) {
whesse@chromium.orge90029b2010-08-02 11:52:17 +0000432 if (FLAG_debug_info) RecordPositions(masm(), fun->end_position() - 1, false);
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +0000433}
434
435
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000436void CodeGenerator::CodeForStatementPosition(Statement* stmt) {
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000437 if (FLAG_debug_info) RecordPositions(masm(), stmt->statement_pos(), false);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000438}
439
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000440
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000441void CodeGenerator::CodeForDoWhileConditionPosition(DoWhileStatement* stmt) {
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000442 if (FLAG_debug_info)
443 RecordPositions(masm(), stmt->condition_position(), false);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000444}
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000445
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000446
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000447void CodeGenerator::CodeForSourcePosition(int pos) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000448 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +0000449 masm()->positions_recorder()->RecordPosition(pos);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000450 }
451}
452
453
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000454const char* GenericUnaryOpStub::GetName() {
455 switch (op_) {
456 case Token::SUB:
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +0000457 if (negative_zero_ == kStrictNegativeZero) {
458 return overwrite_ == UNARY_OVERWRITE
459 ? "GenericUnaryOpStub_SUB_Overwrite_Strict0"
460 : "GenericUnaryOpStub_SUB_Alloc_Strict0";
461 } else {
462 return overwrite_ == UNARY_OVERWRITE
463 ? "GenericUnaryOpStub_SUB_Overwrite_Ignore0"
464 : "GenericUnaryOpStub_SUB_Alloc_Ignore0";
465 }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000466 case Token::BIT_NOT:
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +0000467 return overwrite_ == UNARY_OVERWRITE
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000468 ? "GenericUnaryOpStub_BIT_NOT_Overwrite"
469 : "GenericUnaryOpStub_BIT_NOT_Alloc";
470 default:
471 UNREACHABLE();
472 return "<unknown>";
473 }
474}
475
476
ager@chromium.org7c537e22008-10-16 08:43:32 +0000477void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
478 switch (type_) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000479 case READ_ELEMENT: GenerateReadElement(masm); break;
480 case NEW_OBJECT: GenerateNewObject(masm); break;
481 }
482}
483
484
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000485int CEntryStub::MinorKey() {
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000486 ASSERT(result_size_ == 1 || result_size_ == 2);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000487 int result = save_doubles_ ? 1 : 0;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000488#ifdef _WIN64
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000489 return result | ((result_size_ == 1) ? 0 : 2);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000490#else
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000491 return result;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000492#endif
493}
494
495
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000496} } // namespace v8::internal