Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/frames-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 113
114 // Generate code for a JS function. On entry to the function the receiver 114 // Generate code for a JS function. On entry to the function the receiver
115 // and arguments have been pushed on the stack left to right. The actual 115 // and arguments have been pushed on the stack left to right. The actual
116 // argument count matches the formal parameter count expected by the 116 // argument count matches the formal parameter count expected by the
117 // function. 117 // function.
118 // 118 //
119 // The live registers are: 119 // The live registers are:
120 // o r1: the JS function object being called (i.e., ourselves) 120 // o r1: the JS function object being called (i.e., ourselves)
121 // o cp: our context 121 // o cp: our context
122 // o pp: our caller's constant pool pointer (if FLAG_enable_ool_constant_pool)
122 // o fp: our caller's frame pointer 123 // o fp: our caller's frame pointer
123 // o sp: stack pointer 124 // o sp: stack pointer
124 // o lr: return address 125 // o lr: return address
125 // 126 //
126 // The function builds a JS frame. Please see JavaScriptFrameConstants in 127 // The function builds a JS frame. Please see JavaScriptFrameConstants in
127 // frames-arm.h for its layout. 128 // frames-arm.h for its layout.
128 void FullCodeGenerator::Generate() { 129 void FullCodeGenerator::Generate() {
129 CompilationInfo* info = info_; 130 CompilationInfo* info = info_;
130 handler_table_ = 131 handler_table_ =
131 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 132 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
(...skipping 23 matching lines...) Expand all
155 } 156 }
156 157
157 // Open a frame scope to indicate that there is a frame on the stack. The 158 // Open a frame scope to indicate that there is a frame on the stack. The
158 // MANUAL indicates that the scope shouldn't actually generate code to set up 159 // MANUAL indicates that the scope shouldn't actually generate code to set up
159 // the frame (that is done below). 160 // the frame (that is done below).
160 FrameScope frame_scope(masm_, StackFrame::MANUAL); 161 FrameScope frame_scope(masm_, StackFrame::MANUAL);
161 162
162 info->set_prologue_offset(masm_->pc_offset()); 163 info->set_prologue_offset(masm_->pc_offset());
163 __ Prologue(BUILD_FUNCTION_FRAME); 164 __ Prologue(BUILD_FUNCTION_FRAME);
164 info->AddNoFrameRange(0, masm_->pc_offset()); 165 info->AddNoFrameRange(0, masm_->pc_offset());
166 __ LoadConstantPoolPointerRegister();
165 167
166 { Comment cmnt(masm_, "[ Allocate locals"); 168 { Comment cmnt(masm_, "[ Allocate locals");
167 int locals_count = info->scope()->num_stack_slots(); 169 int locals_count = info->scope()->num_stack_slots();
168 // Generators allocate locals, if any, in context slots. 170 // Generators allocate locals, if any, in context slots.
169 ASSERT(!info->function()->is_generator() || locals_count == 0); 171 ASSERT(!info->function()->is_generator() || locals_count == 0);
170 if (locals_count > 0) { 172 if (locals_count > 0) {
171 // Emit a loop to initialize stack cells for locals when optimizing for 173 // Emit a loop to initialize stack cells for locals when optimizing for
172 // size. Otherwise, unroll the loop for maximum performance. 174 // size. Otherwise, unroll the loop for maximum performance.
173 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); 175 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
174 if (FLAG_optimize_for_size && locals_count > 4) { 176 if (FLAG_optimize_for_size && locals_count > 4) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 329 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
328 __ mov(r2, Operand(profiling_counter_)); 330 __ mov(r2, Operand(profiling_counter_));
329 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); 331 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
330 __ sub(r3, r3, Operand(Smi::FromInt(delta)), SetCC); 332 __ sub(r3, r3, Operand(Smi::FromInt(delta)), SetCC);
331 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset)); 333 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
332 } 334 }
333 335
334 336
335 void FullCodeGenerator::EmitProfilingCounterReset() { 337 void FullCodeGenerator::EmitProfilingCounterReset() {
336 int reset_value = FLAG_interrupt_budget; 338 int reset_value = FLAG_interrupt_budget;
337 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
338 // Self-optimization is a one-off thing: if it fails, don't try again.
339 reset_value = Smi::kMaxValue;
340 }
341 if (isolate()->IsDebuggerActive()) { 339 if (isolate()->IsDebuggerActive()) {
342 // Detect debug break requests as soon as possible. 340 // Detect debug break requests as soon as possible.
343 reset_value = FLAG_interrupt_budget >> 4; 341 reset_value = FLAG_interrupt_budget >> 4;
344 } 342 }
345 __ mov(r2, Operand(profiling_counter_)); 343 __ mov(r2, Operand(profiling_counter_));
346 __ mov(r3, Operand(Smi::FromInt(reset_value))); 344 __ mov(r3, Operand(Smi::FromInt(reset_value)));
347 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset)); 345 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
348 } 346 }
349 347
350 348
351 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 349 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
352 Label* back_edge_target) { 350 Label* back_edge_target) {
353 Comment cmnt(masm_, "[ Back edge bookkeeping"); 351 Comment cmnt(masm_, "[ Back edge bookkeeping");
354 // Block literal pools whilst emitting back edge code. 352 // Block literal pools whilst emitting back edge code.
355 Assembler::BlockConstPoolScope block_const_pool(masm_); 353 Assembler::BlockConstPoolScope block_const_pool(masm_);
356 Label ok; 354 Label ok;
357 355
358 int weight = 1; 356 ASSERT(back_edge_target->is_bound());
359 if (FLAG_weighted_back_edges) { 357 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
360 ASSERT(back_edge_target->is_bound()); 358 int weight = Min(kMaxBackEdgeWeight,
361 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 359 Max(1, distance / kCodeSizeMultiplier));
362 weight = Min(kMaxBackEdgeWeight,
363 Max(1, distance / kCodeSizeMultiplier));
364 }
365 EmitProfilingCounterDecrement(weight); 360 EmitProfilingCounterDecrement(weight);
366 __ b(pl, &ok); 361 __ b(pl, &ok);
367 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 362 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
368 363
369 // Record a mapping of this PC offset to the OSR id. This is used to find 364 // Record a mapping of this PC offset to the OSR id. This is used to find
370 // the AST id from the unoptimized code in order to use it as a key into 365 // the AST id from the unoptimized code in order to use it as a key into
371 // the deoptimization input data found in the optimized code. 366 // the deoptimization input data found in the optimized code.
372 RecordBackEdge(stmt->OsrEntryId()); 367 RecordBackEdge(stmt->OsrEntryId());
373 368
374 EmitProfilingCounterReset(); 369 EmitProfilingCounterReset();
(...skipping 12 matching lines...) Expand all
387 if (return_label_.is_bound()) { 382 if (return_label_.is_bound()) {
388 __ b(&return_label_); 383 __ b(&return_label_);
389 } else { 384 } else {
390 __ bind(&return_label_); 385 __ bind(&return_label_);
391 if (FLAG_trace) { 386 if (FLAG_trace) {
392 // Push the return value on the stack as the parameter. 387 // Push the return value on the stack as the parameter.
393 // Runtime::TraceExit returns its parameter in r0. 388 // Runtime::TraceExit returns its parameter in r0.
394 __ push(r0); 389 __ push(r0);
395 __ CallRuntime(Runtime::kTraceExit, 1); 390 __ CallRuntime(Runtime::kTraceExit, 1);
396 } 391 }
397 if (FLAG_interrupt_at_exit || FLAG_self_optimization) { 392 // Pretend that the exit is a backwards jump to the entry.
398 // Pretend that the exit is a backwards jump to the entry. 393 int weight = 1;
399 int weight = 1; 394 if (info_->ShouldSelfOptimize()) {
400 if (info_->ShouldSelfOptimize()) { 395 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
401 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 396 } else {
402 } else if (FLAG_weighted_back_edges) { 397 int distance = masm_->pc_offset();
403 int distance = masm_->pc_offset(); 398 weight = Min(kMaxBackEdgeWeight,
404 weight = Min(kMaxBackEdgeWeight, 399 Max(1, distance / kCodeSizeMultiplier));
405 Max(1, distance / kCodeSizeMultiplier));
406 }
407 EmitProfilingCounterDecrement(weight);
408 Label ok;
409 __ b(pl, &ok);
410 __ push(r0);
411 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
412 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
413 __ push(r2);
414 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
415 } else {
416 __ Call(isolate()->builtins()->InterruptCheck(),
417 RelocInfo::CODE_TARGET);
418 }
419 __ pop(r0);
420 EmitProfilingCounterReset();
421 __ bind(&ok);
422 } 400 }
401 EmitProfilingCounterDecrement(weight);
402 Label ok;
403 __ b(pl, &ok);
404 __ push(r0);
405 __ Call(isolate()->builtins()->InterruptCheck(),
406 RelocInfo::CODE_TARGET);
407 __ pop(r0);
408 EmitProfilingCounterReset();
409 __ bind(&ok);
423 410
424 #ifdef DEBUG 411 #ifdef DEBUG
425 // Add a label for checking the size of the code used for returning. 412 // Add a label for checking the size of the code used for returning.
426 Label check_exit_codesize; 413 Label check_exit_codesize;
427 masm_->bind(&check_exit_codesize); 414 __ bind(&check_exit_codesize);
428 #endif 415 #endif
429 // Make sure that the constant pool is not emitted inside of the return 416 // Make sure that the constant pool is not emitted inside of the return
430 // sequence. 417 // sequence.
431 { Assembler::BlockConstPoolScope block_const_pool(masm_); 418 { Assembler::BlockConstPoolScope block_const_pool(masm_);
432 // Here we use masm_-> instead of the __ macro to avoid the code coverage
433 // tool from instrumenting as we rely on the code size here.
434 int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize; 419 int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
435 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); 420 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
436 // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5! 421 // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5!
437 PredictableCodeSizeScope predictable(masm_, -1); 422 PredictableCodeSizeScope predictable(masm_, -1);
438 __ RecordJSReturn(); 423 __ RecordJSReturn();
439 masm_->mov(sp, fp); 424 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT);
440 int no_frame_start = masm_->pc_offset(); 425 __ add(sp, sp, Operand(sp_delta));
441 masm_->ldm(ia_w, sp, fp.bit() | lr.bit()); 426 __ Jump(lr);
442 masm_->add(sp, sp, Operand(sp_delta));
443 masm_->Jump(lr);
444 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 427 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
445 } 428 }
446 429
447 #ifdef DEBUG 430 #ifdef DEBUG
448 // Check that the size of the code used for returning is large enough 431 // Check that the size of the code used for returning is large enough
449 // for the debugger's requirements. 432 // for the debugger's requirements.
450 ASSERT(Assembler::kJSReturnSequenceInstructions <= 433 ASSERT(Assembler::kJSReturnSequenceInstructions <=
451 masm_->InstructionsGeneratedSince(&check_exit_codesize)); 434 masm_->InstructionsGeneratedSince(&check_exit_codesize));
452 #endif 435 #endif
453 } 436 }
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 __ b(clause->body_target()); 1016 __ b(clause->body_target());
1034 __ bind(&slow_case); 1017 __ bind(&slow_case);
1035 } 1018 }
1036 1019
1037 // Record position before stub call for type feedback. 1020 // Record position before stub call for type feedback.
1038 SetSourcePosition(clause->position()); 1021 SetSourcePosition(clause->position());
1039 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1022 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
1040 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); 1023 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
1041 patch_site.EmitPatchInfo(); 1024 patch_site.EmitPatchInfo();
1042 1025
1026 Label skip;
1027 __ b(&skip);
1028 PrepareForBailout(clause, TOS_REG);
1029 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
1030 __ cmp(r0, ip);
1031 __ b(ne, &next_test);
1032 __ Drop(1);
1033 __ jmp(clause->body_target());
1034 __ bind(&skip);
1035
1043 __ cmp(r0, Operand::Zero()); 1036 __ cmp(r0, Operand::Zero());
1044 __ b(ne, &next_test); 1037 __ b(ne, &next_test);
1045 __ Drop(1); // Switch value is no longer needed. 1038 __ Drop(1); // Switch value is no longer needed.
1046 __ b(clause->body_target()); 1039 __ b(clause->body_target());
1047 } 1040 }
1048 1041
1049 // Discard the test value and jump to the default if present, otherwise to 1042 // Discard the test value and jump to the default if present, otherwise to
1050 // the end of the statement. 1043 // the end of the statement.
1051 __ bind(&next_test); 1044 __ bind(&next_test);
1052 __ Drop(1); // Switch value is no longer needed. 1045 __ Drop(1); // Switch value is no longer needed.
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 2155
2163 // Enter a new JavaScript frame, and initialize its slots as they were when 2156 // Enter a new JavaScript frame, and initialize its slots as they were when
2164 // the generator was suspended. 2157 // the generator was suspended.
2165 Label resume_frame; 2158 Label resume_frame;
2166 __ bind(&push_frame); 2159 __ bind(&push_frame);
2167 __ bl(&resume_frame); 2160 __ bl(&resume_frame);
2168 __ jmp(&done); 2161 __ jmp(&done);
2169 __ bind(&resume_frame); 2162 __ bind(&resume_frame);
2170 // lr = return address. 2163 // lr = return address.
2171 // fp = caller's frame pointer. 2164 // fp = caller's frame pointer.
2165 // pp = caller's constant pool (if FLAG_enable_ool_constant_pool),
2172 // cp = callee's context, 2166 // cp = callee's context,
2173 // r4 = callee's JS function. 2167 // r4 = callee's JS function.
2174 __ Push(lr, fp, cp, r4); 2168 __ PushFixedFrame(r4);
2175 // Adjust FP to point to saved FP. 2169 // Adjust FP to point to saved FP.
2176 __ add(fp, sp, Operand(2 * kPointerSize)); 2170 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
2177 2171
2178 // Load the operand stack size. 2172 // Load the operand stack size.
2179 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset)); 2173 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset));
2180 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset)); 2174 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset));
2181 __ SmiUntag(r3); 2175 __ SmiUntag(r3);
2182 2176
2183 // If we are sending a value and there is no operand stack, we can jump back 2177 // If we are sending a value and there is no operand stack, we can jump back
2184 // in directly. 2178 // in directly.
2185 if (resume_mode == JSGeneratorObject::NEXT) { 2179 if (resume_mode == JSGeneratorObject::NEXT) {
2186 Label slow_resume; 2180 Label slow_resume;
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 __ ldr(r1, GlobalObjectOperand()); 2441 __ ldr(r1, GlobalObjectOperand());
2448 Handle<Code> ic = is_classic_mode() 2442 Handle<Code> ic = is_classic_mode()
2449 ? isolate()->builtins()->StoreIC_Initialize() 2443 ? isolate()->builtins()->StoreIC_Initialize()
2450 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2444 : isolate()->builtins()->StoreIC_Initialize_Strict();
2451 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 2445 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
2452 2446
2453 } else if (op == Token::INIT_CONST) { 2447 } else if (op == Token::INIT_CONST) {
2454 // Const initializers need a write barrier. 2448 // Const initializers need a write barrier.
2455 ASSERT(!var->IsParameter()); // No const parameters. 2449 ASSERT(!var->IsParameter()); // No const parameters.
2456 if (var->IsStackLocal()) { 2450 if (var->IsStackLocal()) {
2457 Label skip;
2458 __ ldr(r1, StackOperand(var)); 2451 __ ldr(r1, StackOperand(var));
2459 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); 2452 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
2460 __ b(ne, &skip); 2453 __ str(result_register(), StackOperand(var), eq);
2461 __ str(result_register(), StackOperand(var));
2462 __ bind(&skip);
2463 } else { 2454 } else {
2464 ASSERT(var->IsContextSlot() || var->IsLookupSlot()); 2455 ASSERT(var->IsContextSlot() || var->IsLookupSlot());
2465 // Like var declarations, const declarations are hoisted to function 2456 // Like var declarations, const declarations are hoisted to function
2466 // scope. However, unlike var initializers, const initializers are 2457 // scope. However, unlike var initializers, const initializers are
2467 // able to drill a hole to that function context, even from inside a 2458 // able to drill a hole to that function context, even from inside a
2468 // 'with' context. We thus bypass the normal static scope lookup for 2459 // 'with' context. We thus bypass the normal static scope lookup for
2469 // var->IsContextSlot(). 2460 // var->IsContextSlot().
2470 __ push(r0); 2461 __ push(r0);
2471 __ mov(r0, Operand(var->name())); 2462 __ mov(r0, Operand(var->name()));
2472 __ Push(cp, r0); // Context and name. 2463 __ Push(cp, r0); // Context and name.
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 Label* if_true = NULL; 3180 Label* if_true = NULL;
3190 Label* if_false = NULL; 3181 Label* if_false = NULL;
3191 Label* fall_through = NULL; 3182 Label* fall_through = NULL;
3192 context()->PrepareTest(&materialize_true, &materialize_false, 3183 context()->PrepareTest(&materialize_true, &materialize_false,
3193 &if_true, &if_false, &fall_through); 3184 &if_true, &if_false, &fall_through);
3194 3185
3195 // Get the frame pointer for the calling frame. 3186 // Get the frame pointer for the calling frame.
3196 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3187 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3197 3188
3198 // Skip the arguments adaptor frame if it exists. 3189 // Skip the arguments adaptor frame if it exists.
3199 Label check_frame_marker;
3200 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); 3190 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset));
3201 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3191 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3202 __ b(ne, &check_frame_marker); 3192 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset), eq);
3203 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset));
3204 3193
3205 // Check the marker in the calling frame. 3194 // Check the marker in the calling frame.
3206 __ bind(&check_frame_marker);
3207 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); 3195 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
3208 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 3196 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
3209 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3197 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3210 Split(eq, if_true, if_false, fall_through); 3198 Split(eq, if_true, if_false, fall_through);
3211 3199
3212 context()->Plug(if_true, if_false); 3200 context()->Plug(if_true, if_false);
3213 } 3201 }
3214 3202
3215 3203
3216 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { 3204 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
(...skipping 30 matching lines...) Expand all
3247 __ mov(r1, r0); 3235 __ mov(r1, r0);
3248 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); 3236 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
3249 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 3237 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
3250 __ CallStub(&stub); 3238 __ CallStub(&stub);
3251 context()->Plug(r0); 3239 context()->Plug(r0);
3252 } 3240 }
3253 3241
3254 3242
3255 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { 3243 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
3256 ASSERT(expr->arguments()->length() == 0); 3244 ASSERT(expr->arguments()->length() == 0);
3257 Label exit; 3245
3258 // Get the number of formal parameters. 3246 // Get the number of formal parameters.
3259 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); 3247 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
3260 3248
3261 // Check if the calling frame is an arguments adaptor frame. 3249 // Check if the calling frame is an arguments adaptor frame.
3262 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3250 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3263 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 3251 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
3264 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3252 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3265 __ b(ne, &exit);
3266 3253
3267 // Arguments adaptor case: Read the arguments length from the 3254 // Arguments adaptor case: Read the arguments length from the
3268 // adaptor frame. 3255 // adaptor frame.
3269 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3256 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset), eq);
3270 3257
3271 __ bind(&exit);
3272 context()->Plug(r0); 3258 context()->Plug(r0);
3273 } 3259 }
3274 3260
3275 3261
3276 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { 3262 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
3277 ZoneList<Expression*>* args = expr->arguments(); 3263 ZoneList<Expression*>* args = expr->arguments();
3278 ASSERT(args->length() == 1); 3264 ASSERT(args->length() == 1);
3279 Label done, null, function, non_function_constructor; 3265 Label done, null, function, non_function_constructor;
3280 3266
3281 VisitForAccumulatorValue(args->at(0)); 3267 VisitForAccumulatorValue(args->at(0));
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3386 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { 3372 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
3387 ZoneList<Expression*>* args = expr->arguments(); 3373 ZoneList<Expression*>* args = expr->arguments();
3388 ASSERT(args->length() == 1); 3374 ASSERT(args->length() == 1);
3389 VisitForAccumulatorValue(args->at(0)); // Load the object. 3375 VisitForAccumulatorValue(args->at(0)); // Load the object.
3390 3376
3391 Label done; 3377 Label done;
3392 // If the object is a smi return the object. 3378 // If the object is a smi return the object.
3393 __ JumpIfSmi(r0, &done); 3379 __ JumpIfSmi(r0, &done);
3394 // If the object is not a value type, return the object. 3380 // If the object is not a value type, return the object.
3395 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); 3381 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE);
3396 __ b(ne, &done); 3382 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset), eq);
3397 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
3398 3383
3399 __ bind(&done); 3384 __ bind(&done);
3400 context()->Plug(r0); 3385 context()->Plug(r0);
3401 } 3386 }
3402 3387
3403 3388
3404 void FullCodeGenerator::EmitDateField(CallRuntime* expr) { 3389 void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
3405 ZoneList<Expression*>* args = expr->arguments(); 3390 ZoneList<Expression*>* args = expr->arguments();
3406 ASSERT(args->length() == 2); 3391 ASSERT(args->length() == 2);
3407 ASSERT_NE(NULL, args->at(1)->AsLiteral()); 3392 ASSERT_NE(NULL, args->at(1)->AsLiteral());
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
3706 VisitForStackValue(args->at(0)); 3691 VisitForStackValue(args->at(0));
3707 VisitForStackValue(args->at(1)); 3692 VisitForStackValue(args->at(1));
3708 3693
3709 StringCompareStub stub; 3694 StringCompareStub stub;
3710 __ CallStub(&stub); 3695 __ CallStub(&stub);
3711 context()->Plug(r0); 3696 context()->Plug(r0);
3712 } 3697 }
3713 3698
3714 3699
3715 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { 3700 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
3716 // Load the argument on the stack and call the stub. 3701 // Load the argument on the stack and call the runtime function.
3717 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3718 TranscendentalCacheStub::TAGGED);
3719 ZoneList<Expression*>* args = expr->arguments(); 3702 ZoneList<Expression*>* args = expr->arguments();
3720 ASSERT(args->length() == 1); 3703 ASSERT(args->length() == 1);
3721 VisitForStackValue(args->at(0)); 3704 VisitForStackValue(args->at(0));
3722 __ CallStub(&stub); 3705 __ CallRuntime(Runtime::kMath_log, 1);
3723 context()->Plug(r0); 3706 context()->Plug(r0);
3724 } 3707 }
3725 3708
3726 3709
3727 void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) { 3710 void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
3728 // Load the argument on the stack and call the runtime function. 3711 // Load the argument on the stack and call the runtime function.
3729 ZoneList<Expression*>* args = expr->arguments(); 3712 ZoneList<Expression*>* args = expr->arguments();
3730 ASSERT(args->length() == 1); 3713 ASSERT(args->length() == 1);
3731 VisitForStackValue(args->at(0)); 3714 VisitForStackValue(args->at(0));
3732 __ CallRuntime(Runtime::kMath_sqrt, 1); 3715 __ CallRuntime(Runtime::kMath_sqrt, 1);
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
4928 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4911 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4929 reinterpret_cast<uint32_t>( 4912 reinterpret_cast<uint32_t>(
4930 isolate->builtins()->OsrAfterStackCheck()->entry())); 4913 isolate->builtins()->OsrAfterStackCheck()->entry()));
4931 return OSR_AFTER_STACK_CHECK; 4914 return OSR_AFTER_STACK_CHECK;
4932 } 4915 }
4933 4916
4934 4917
4935 } } // namespace v8::internal 4918 } } // namespace v8::internal
4936 4919
4937 #endif // V8_TARGET_ARCH_ARM 4920 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/frames-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698