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

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

Issue 204293004: A64: Remove Operand constructors where an implicit constructor can be used. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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/a64/deoptimizer-a64.cc ('k') | src/a64/ic-a64.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 if (!function_in_register_x1) { 236 if (!function_in_register_x1) {
237 // Load this again, if it's used by the local context below. 237 // Load this again, if it's used by the local context below.
238 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 238 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
239 } else { 239 } else {
240 __ Mov(x3, x1); 240 __ Mov(x3, x1);
241 } 241 }
242 // Receiver is just before the parameters on the caller's stack. 242 // Receiver is just before the parameters on the caller's stack.
243 int num_parameters = info->scope()->num_parameters(); 243 int num_parameters = info->scope()->num_parameters();
244 int offset = num_parameters * kPointerSize; 244 int offset = num_parameters * kPointerSize;
245 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset); 245 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset);
246 __ Mov(x1, Operand(Smi::FromInt(num_parameters))); 246 __ Mov(x1, Smi::FromInt(num_parameters));
247 __ Push(x3, x2, x1); 247 __ Push(x3, x2, x1);
248 248
249 // Arguments to ArgumentsAccessStub: 249 // Arguments to ArgumentsAccessStub:
250 // function, receiver address, parameter count. 250 // function, receiver address, parameter count.
251 // The stub will rewrite receiver and parameter count if the previous 251 // The stub will rewrite receiver and parameter count if the previous
252 // stack frame was an arguments adapter frame. 252 // stack frame was an arguments adapter frame.
253 ArgumentsAccessStub::Type type; 253 ArgumentsAccessStub::Type type;
254 if (strict_mode() == STRICT) { 254 if (strict_mode() == STRICT) {
255 type = ArgumentsAccessStub::NEW_STRICT; 255 type = ArgumentsAccessStub::NEW_STRICT;
256 } else if (function()->has_duplicate_parameters()) { 256 } else if (function()->has_duplicate_parameters()) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 EmitReturnSequence(); 315 EmitReturnSequence();
316 316
317 // Force emission of the pools, so they don't get emitted in the middle 317 // Force emission of the pools, so they don't get emitted in the middle
318 // of the back edge table. 318 // of the back edge table.
319 masm()->CheckVeneerPool(true, false); 319 masm()->CheckVeneerPool(true, false);
320 masm()->CheckConstPool(true, false); 320 masm()->CheckConstPool(true, false);
321 } 321 }
322 322
323 323
324 void FullCodeGenerator::ClearAccumulator() { 324 void FullCodeGenerator::ClearAccumulator() {
325 __ Mov(x0, Operand(Smi::FromInt(0))); 325 __ Mov(x0, Smi::FromInt(0));
326 } 326 }
327 327
328 328
329 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 329 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
330 __ Mov(x2, Operand(profiling_counter_)); 330 __ Mov(x2, Operand(profiling_counter_));
331 __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset)); 331 __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset));
332 __ Subs(x3, x3, Operand(Smi::FromInt(delta))); 332 __ Subs(x3, x3, Smi::FromInt(delta));
333 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset)); 333 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset));
334 } 334 }
335 335
336 336
337 void FullCodeGenerator::EmitProfilingCounterReset() { 337 void FullCodeGenerator::EmitProfilingCounterReset() {
338 int reset_value = FLAG_interrupt_budget; 338 int reset_value = FLAG_interrupt_budget;
339 if (isolate()->IsDebuggerActive()) { 339 if (isolate()->IsDebuggerActive()) {
340 // Detect debug break requests as soon as possible. 340 // Detect debug break requests as soon as possible.
341 reset_value = FLAG_interrupt_budget >> 4; 341 reset_value = FLAG_interrupt_budget >> 4;
342 } 342 }
343 __ Mov(x2, Operand(profiling_counter_)); 343 __ Mov(x2, Operand(profiling_counter_));
344 __ Mov(x3, Operand(Smi::FromInt(reset_value))); 344 __ Mov(x3, Smi::FromInt(reset_value));
345 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset)); 345 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset));
346 } 346 }
347 347
348 348
349 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 349 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
350 Label* back_edge_target) { 350 Label* back_edge_target) {
351 ASSERT(jssp.Is(__ StackPointer())); 351 ASSERT(jssp.Is(__ StackPointer()));
352 Comment cmnt(masm_, "[ Back edge bookkeeping"); 352 Comment cmnt(masm_, "[ Back edge bookkeeping");
353 // Block literal pools whilst emitting back edge code. 353 // Block literal pools whilst emitting back edge code.
354 Assembler::BlockPoolsScope block_const_pool(masm_); 354 Assembler::BlockPoolsScope block_const_pool(masm_);
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 } 824 }
825 break; 825 break;
826 826
827 case Variable::LOOKUP: { 827 case Variable::LOOKUP: {
828 Comment cmnt(masm_, "[ VariableDeclaration"); 828 Comment cmnt(masm_, "[ VariableDeclaration");
829 __ Mov(x2, Operand(variable->name())); 829 __ Mov(x2, Operand(variable->name()));
830 // Declaration nodes are always introduced in one of four modes. 830 // Declaration nodes are always introduced in one of four modes.
831 ASSERT(IsDeclaredVariableMode(mode)); 831 ASSERT(IsDeclaredVariableMode(mode));
832 PropertyAttributes attr = IsImmutableVariableMode(mode) ? READ_ONLY 832 PropertyAttributes attr = IsImmutableVariableMode(mode) ? READ_ONLY
833 : NONE; 833 : NONE;
834 __ Mov(x1, Operand(Smi::FromInt(attr))); 834 __ Mov(x1, Smi::FromInt(attr));
835 // Push initial value, if any. 835 // Push initial value, if any.
836 // Note: For variables we must not push an initial value (such as 836 // Note: For variables we must not push an initial value (such as
837 // 'undefined') because we may have a (legal) redeclaration and we 837 // 'undefined') because we may have a (legal) redeclaration and we
838 // must not destroy the current value. 838 // must not destroy the current value.
839 if (hole_init) { 839 if (hole_init) {
840 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); 840 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex);
841 __ Push(cp, x2, x1, x0); 841 __ Push(cp, x2, x1, x0);
842 } else { 842 } else {
843 // Pushing 0 (xzr) indicates no initial value. 843 // Pushing 0 (xzr) indicates no initial value.
844 __ Push(cp, x2, x1, xzr); 844 __ Push(cp, x2, x1, xzr);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 kDontSaveFPRegs, 888 kDontSaveFPRegs,
889 EMIT_REMEMBERED_SET, 889 EMIT_REMEMBERED_SET,
890 OMIT_SMI_CHECK); 890 OMIT_SMI_CHECK);
891 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 891 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
892 break; 892 break;
893 } 893 }
894 894
895 case Variable::LOOKUP: { 895 case Variable::LOOKUP: {
896 Comment cmnt(masm_, "[ Function Declaration"); 896 Comment cmnt(masm_, "[ Function Declaration");
897 __ Mov(x2, Operand(variable->name())); 897 __ Mov(x2, Operand(variable->name()));
898 __ Mov(x1, Operand(Smi::FromInt(NONE))); 898 __ Mov(x1, Smi::FromInt(NONE));
899 __ Push(cp, x2, x1); 899 __ Push(cp, x2, x1);
900 // Push initial value for function declaration. 900 // Push initial value for function declaration.
901 VisitForStackValue(declaration->fun()); 901 VisitForStackValue(declaration->fun());
902 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 902 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
903 break; 903 break;
904 } 904 }
905 } 905 }
906 } 906 }
907 907
908 908
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 // TODO(rossberg) 964 // TODO(rossberg)
965 } 965 }
966 966
967 967
968 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 968 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
969 // Call the runtime to declare the globals. 969 // Call the runtime to declare the globals.
970 __ Mov(x11, Operand(pairs)); 970 __ Mov(x11, Operand(pairs));
971 Register flags = xzr; 971 Register flags = xzr;
972 if (Smi::FromInt(DeclareGlobalsFlags())) { 972 if (Smi::FromInt(DeclareGlobalsFlags())) {
973 flags = x10; 973 flags = x10;
974 __ Mov(flags, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 974 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags()));
975 } 975 }
976 __ Push(cp, x11, flags); 976 __ Push(cp, x11, flags);
977 __ CallRuntime(Runtime::kDeclareGlobals, 3); 977 __ CallRuntime(Runtime::kDeclareGlobals, 3);
978 // Return value is ignored. 978 // Return value is ignored.
979 } 979 }
980 980
981 981
982 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 982 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
983 // Call the runtime to declare the modules. 983 // Call the runtime to declare the modules.
984 __ Push(descriptions); 984 __ Push(descriptions);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 __ EnumLengthUntagged(x1, x0); 1143 __ EnumLengthUntagged(x1, x0);
1144 __ Cbz(x1, &no_descriptors); 1144 __ Cbz(x1, &no_descriptors);
1145 1145
1146 __ LoadInstanceDescriptors(x0, x2); 1146 __ LoadInstanceDescriptors(x0, x2);
1147 __ Ldr(x2, FieldMemOperand(x2, DescriptorArray::kEnumCacheOffset)); 1147 __ Ldr(x2, FieldMemOperand(x2, DescriptorArray::kEnumCacheOffset));
1148 __ Ldr(x2, 1148 __ Ldr(x2,
1149 FieldMemOperand(x2, DescriptorArray::kEnumCacheBridgeCacheOffset)); 1149 FieldMemOperand(x2, DescriptorArray::kEnumCacheBridgeCacheOffset));
1150 1150
1151 // Set up the four remaining stack slots. 1151 // Set up the four remaining stack slots.
1152 __ Push(x0); // Map. 1152 __ Push(x0); // Map.
1153 __ Mov(x0, Operand(Smi::FromInt(0))); 1153 __ Mov(x0, Smi::FromInt(0));
1154 // Push enumeration cache, enumeration cache length (as smi) and zero. 1154 // Push enumeration cache, enumeration cache length (as smi) and zero.
1155 __ SmiTag(x1); 1155 __ SmiTag(x1);
1156 __ Push(x2, x1, x0); 1156 __ Push(x2, x1, x0);
1157 __ B(&loop); 1157 __ B(&loop);
1158 1158
1159 __ Bind(&no_descriptors); 1159 __ Bind(&no_descriptors);
1160 __ Drop(1); 1160 __ Drop(1);
1161 __ B(&exit); 1161 __ B(&exit);
1162 1162
1163 // We got a fixed array in register x0. Iterate through that. 1163 // We got a fixed array in register x0. Iterate through that.
1164 __ Bind(&fixed_array); 1164 __ Bind(&fixed_array);
1165 1165
1166 Handle<Object> feedback = Handle<Object>( 1166 Handle<Object> feedback = Handle<Object>(
1167 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker), 1167 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1168 isolate()); 1168 isolate());
1169 StoreFeedbackVectorSlot(slot, feedback); 1169 StoreFeedbackVectorSlot(slot, feedback);
1170 __ LoadObject(x1, FeedbackVector()); 1170 __ LoadObject(x1, FeedbackVector());
1171 __ Mov(x10, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker))); 1171 __ Mov(x10, Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker));
1172 __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot))); 1172 __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot)));
1173 1173
1174 __ Mov(x1, Operand(Smi::FromInt(1))); // Smi indicates slow check. 1174 __ Mov(x1, Smi::FromInt(1)); // Smi indicates slow check.
1175 __ Peek(x10, 0); // Get enumerated object. 1175 __ Peek(x10, 0); // Get enumerated object.
1176 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1176 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1177 // TODO(all): similar check was done already. Can we avoid it here? 1177 // TODO(all): similar check was done already. Can we avoid it here?
1178 __ CompareObjectType(x10, x11, x12, LAST_JS_PROXY_TYPE); 1178 __ CompareObjectType(x10, x11, x12, LAST_JS_PROXY_TYPE);
1179 ASSERT(Smi::FromInt(0) == 0); 1179 ASSERT(Smi::FromInt(0) == 0);
1180 __ CzeroX(x1, le); // Zero indicates proxy. 1180 __ CzeroX(x1, le); // Zero indicates proxy.
1181 __ Push(x1, x0); // Smi and array 1181 __ Push(x1, x0); // Smi and array
1182 __ Ldr(x1, FieldMemOperand(x0, FixedArray::kLengthOffset)); 1182 __ Ldr(x1, FieldMemOperand(x0, FixedArray::kLengthOffset));
1183 __ Push(x1, xzr); // Fixed array length (as smi) and initial index. 1183 __ Push(x1, xzr); // Fixed array length (as smi) and initial index.
1184 1184
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 } 1230 }
1231 1231
1232 // Generate code for the body of the loop. 1232 // Generate code for the body of the loop.
1233 Visit(stmt->body()); 1233 Visit(stmt->body());
1234 1234
1235 // Generate code for going to the next element by incrementing 1235 // Generate code for going to the next element by incrementing
1236 // the index (smi) stored on top of the stack. 1236 // the index (smi) stored on top of the stack.
1237 __ Bind(loop_statement.continue_label()); 1237 __ Bind(loop_statement.continue_label());
1238 // TODO(all): We could use a callee saved register to avoid popping. 1238 // TODO(all): We could use a callee saved register to avoid popping.
1239 __ Pop(x0); 1239 __ Pop(x0);
1240 __ Add(x0, x0, Operand(Smi::FromInt(1))); 1240 __ Add(x0, x0, Smi::FromInt(1));
1241 __ Push(x0); 1241 __ Push(x0);
1242 1242
1243 EmitBackEdgeBookkeeping(stmt, &loop); 1243 EmitBackEdgeBookkeeping(stmt, &loop);
1244 __ B(&loop); 1244 __ B(&loop);
1245 1245
1246 // Remove the pointers stored on the stack. 1246 // Remove the pointers stored on the stack.
1247 __ Bind(loop_statement.break_label()); 1247 __ Bind(loop_statement.break_label());
1248 __ Drop(5); 1248 __ Drop(5);
1249 1249
1250 // Exit and decrement the loop depth. 1250 // Exit and decrement the loop depth.
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 // x0 = RegExp literal clone 1575 // x0 = RegExp literal clone
1576 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1576 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1577 __ Ldr(x4, FieldMemOperand(x10, JSFunction::kLiteralsOffset)); 1577 __ Ldr(x4, FieldMemOperand(x10, JSFunction::kLiteralsOffset));
1578 int literal_offset = 1578 int literal_offset =
1579 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1579 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1580 __ Ldr(x5, FieldMemOperand(x4, literal_offset)); 1580 __ Ldr(x5, FieldMemOperand(x4, literal_offset));
1581 __ JumpIfNotRoot(x5, Heap::kUndefinedValueRootIndex, &materialized); 1581 __ JumpIfNotRoot(x5, Heap::kUndefinedValueRootIndex, &materialized);
1582 1582
1583 // Create regexp literal using runtime function. 1583 // Create regexp literal using runtime function.
1584 // Result will be in x0. 1584 // Result will be in x0.
1585 __ Mov(x3, Operand(Smi::FromInt(expr->literal_index()))); 1585 __ Mov(x3, Smi::FromInt(expr->literal_index()));
1586 __ Mov(x2, Operand(expr->pattern())); 1586 __ Mov(x2, Operand(expr->pattern()));
1587 __ Mov(x1, Operand(expr->flags())); 1587 __ Mov(x1, Operand(expr->flags()));
1588 __ Push(x4, x3, x2, x1); 1588 __ Push(x4, x3, x2, x1);
1589 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1589 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1590 __ Mov(x5, x0); 1590 __ Mov(x5, x0);
1591 1591
1592 __ Bind(&materialized); 1592 __ Bind(&materialized);
1593 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1593 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1594 Label allocated, runtime_allocate; 1594 Label allocated, runtime_allocate;
1595 __ Allocate(size, x0, x2, x3, &runtime_allocate, TAG_OBJECT); 1595 __ Allocate(size, x0, x2, x3, &runtime_allocate, TAG_OBJECT);
1596 __ B(&allocated); 1596 __ B(&allocated);
1597 1597
1598 __ Bind(&runtime_allocate); 1598 __ Bind(&runtime_allocate);
1599 __ Mov(x10, Operand(Smi::FromInt(size))); 1599 __ Mov(x10, Smi::FromInt(size));
1600 __ Push(x5, x10); 1600 __ Push(x5, x10);
1601 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1601 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1602 __ Pop(x5); 1602 __ Pop(x5);
1603 1603
1604 __ Bind(&allocated); 1604 __ Bind(&allocated);
1605 // After this, registers are used as follows: 1605 // After this, registers are used as follows:
1606 // x0: Newly allocated regexp. 1606 // x0: Newly allocated regexp.
1607 // x5: Materialized regexp. 1607 // x5: Materialized regexp.
1608 // x10, x11, x12: temps. 1608 // x10, x11, x12: temps.
1609 __ CopyFields(x0, x5, CPURegList(x10, x11, x12), size / kPointerSize); 1609 __ CopyFields(x0, x5, CPURegList(x10, x11, x12), size / kPointerSize);
(...skipping 11 matching lines...) Expand all
1621 } 1621 }
1622 1622
1623 1623
1624 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1624 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1625 Comment cmnt(masm_, "[ ObjectLiteral"); 1625 Comment cmnt(masm_, "[ ObjectLiteral");
1626 1626
1627 expr->BuildConstantProperties(isolate()); 1627 expr->BuildConstantProperties(isolate());
1628 Handle<FixedArray> constant_properties = expr->constant_properties(); 1628 Handle<FixedArray> constant_properties = expr->constant_properties();
1629 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1629 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1630 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset)); 1630 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset));
1631 __ Mov(x2, Operand(Smi::FromInt(expr->literal_index()))); 1631 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1632 __ Mov(x1, Operand(constant_properties)); 1632 __ Mov(x1, Operand(constant_properties));
1633 int flags = expr->fast_elements() 1633 int flags = expr->fast_elements()
1634 ? ObjectLiteral::kFastElements 1634 ? ObjectLiteral::kFastElements
1635 : ObjectLiteral::kNoFlags; 1635 : ObjectLiteral::kNoFlags;
1636 flags |= expr->has_function() 1636 flags |= expr->has_function()
1637 ? ObjectLiteral::kHasFunction 1637 ? ObjectLiteral::kHasFunction
1638 : ObjectLiteral::kNoFlags; 1638 : ObjectLiteral::kNoFlags;
1639 __ Mov(x0, Operand(Smi::FromInt(flags))); 1639 __ Mov(x0, Smi::FromInt(flags));
1640 int properties_count = constant_properties->length() / 2; 1640 int properties_count = constant_properties->length() / 2;
1641 const int max_cloned_properties = 1641 const int max_cloned_properties =
1642 FastCloneShallowObjectStub::kMaximumClonedProperties; 1642 FastCloneShallowObjectStub::kMaximumClonedProperties;
1643 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || 1643 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
1644 flags != ObjectLiteral::kFastElements || 1644 flags != ObjectLiteral::kFastElements ||
1645 properties_count > max_cloned_properties) { 1645 properties_count > max_cloned_properties) {
1646 __ Push(x3, x2, x1, x0); 1646 __ Push(x3, x2, x1, x0);
1647 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1647 __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
1648 } else { 1648 } else {
1649 FastCloneShallowObjectStub stub(properties_count); 1649 FastCloneShallowObjectStub stub(properties_count);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 VisitForEffect(value); 1688 VisitForEffect(value);
1689 } 1689 }
1690 break; 1690 break;
1691 } 1691 }
1692 if (property->emit_store()) { 1692 if (property->emit_store()) {
1693 // Duplicate receiver on stack. 1693 // Duplicate receiver on stack.
1694 __ Peek(x0, 0); 1694 __ Peek(x0, 0);
1695 __ Push(x0); 1695 __ Push(x0);
1696 VisitForStackValue(key); 1696 VisitForStackValue(key);
1697 VisitForStackValue(value); 1697 VisitForStackValue(value);
1698 __ Mov(x0, Operand(Smi::FromInt(NONE))); // PropertyAttributes 1698 __ Mov(x0, Smi::FromInt(NONE)); // PropertyAttributes
1699 __ Push(x0); 1699 __ Push(x0);
1700 __ CallRuntime(Runtime::kSetProperty, 4); 1700 __ CallRuntime(Runtime::kSetProperty, 4);
1701 } else { 1701 } else {
1702 VisitForEffect(key); 1702 VisitForEffect(key);
1703 VisitForEffect(value); 1703 VisitForEffect(value);
1704 } 1704 }
1705 break; 1705 break;
1706 case ObjectLiteral::Property::PROTOTYPE: 1706 case ObjectLiteral::Property::PROTOTYPE:
1707 if (property->emit_store()) { 1707 if (property->emit_store()) {
1708 // Duplicate receiver on stack. 1708 // Duplicate receiver on stack.
(...skipping 17 matching lines...) Expand all
1726 // Emit code to define accessors, using only a single call to the runtime for 1726 // Emit code to define accessors, using only a single call to the runtime for
1727 // each pair of corresponding getters and setters. 1727 // each pair of corresponding getters and setters.
1728 for (AccessorTable::Iterator it = accessor_table.begin(); 1728 for (AccessorTable::Iterator it = accessor_table.begin();
1729 it != accessor_table.end(); 1729 it != accessor_table.end();
1730 ++it) { 1730 ++it) {
1731 __ Peek(x10, 0); // Duplicate receiver. 1731 __ Peek(x10, 0); // Duplicate receiver.
1732 __ Push(x10); 1732 __ Push(x10);
1733 VisitForStackValue(it->first); 1733 VisitForStackValue(it->first);
1734 EmitAccessor(it->second->getter); 1734 EmitAccessor(it->second->getter);
1735 EmitAccessor(it->second->setter); 1735 EmitAccessor(it->second->setter);
1736 __ Mov(x10, Operand(Smi::FromInt(NONE))); 1736 __ Mov(x10, Smi::FromInt(NONE));
1737 __ Push(x10); 1737 __ Push(x10);
1738 __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5); 1738 __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
1739 } 1739 }
1740 1740
1741 if (expr->has_function()) { 1741 if (expr->has_function()) {
1742 ASSERT(result_saved); 1742 ASSERT(result_saved);
1743 __ Peek(x0, 0); 1743 __ Peek(x0, 0);
1744 __ Push(x0); 1744 __ Push(x0);
1745 __ CallRuntime(Runtime::kToFastProperties, 1); 1745 __ CallRuntime(Runtime::kToFastProperties, 1);
1746 } 1746 }
(...skipping 25 matching lines...) Expand all
1772 1772
1773 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE; 1773 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
1774 if (has_fast_elements && !FLAG_allocation_site_pretenuring) { 1774 if (has_fast_elements && !FLAG_allocation_site_pretenuring) {
1775 // If the only customer of allocation sites is transitioning, then 1775 // If the only customer of allocation sites is transitioning, then
1776 // we can turn it off if we don't have anywhere else to transition to. 1776 // we can turn it off if we don't have anywhere else to transition to.
1777 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1777 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1778 } 1778 }
1779 1779
1780 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1780 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1781 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset)); 1781 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset));
1782 // TODO(jbramley): Can these Operand constructors be implicit? 1782 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1783 __ Mov(x2, Operand(Smi::FromInt(expr->literal_index())));
1784 __ Mov(x1, Operand(constant_elements)); 1783 __ Mov(x1, Operand(constant_elements));
1785 if (has_fast_elements && constant_elements_values->map() == 1784 if (has_fast_elements && constant_elements_values->map() ==
1786 isolate()->heap()->fixed_cow_array_map()) { 1785 isolate()->heap()->fixed_cow_array_map()) {
1787 FastCloneShallowArrayStub stub( 1786 FastCloneShallowArrayStub stub(
1788 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, 1787 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
1789 allocation_site_mode, 1788 allocation_site_mode,
1790 length); 1789 length);
1791 __ CallStub(&stub); 1790 __ CallStub(&stub);
1792 __ IncrementCounter( 1791 __ IncrementCounter(
1793 isolate()->counters()->cow_arrays_created_stub(), 1, x10, x11); 1792 isolate()->counters()->cow_arrays_created_stub(), 1, x10, x11);
1794 } else if ((expr->depth() > 1) || Serializer::enabled() || 1793 } else if ((expr->depth() > 1) || Serializer::enabled() ||
1795 length > FastCloneShallowArrayStub::kMaximumClonedLength) { 1794 length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1796 __ Mov(x0, Operand(Smi::FromInt(flags))); 1795 __ Mov(x0, Smi::FromInt(flags));
1797 __ Push(x3, x2, x1, x0); 1796 __ Push(x3, x2, x1, x0);
1798 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1797 __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
1799 } else { 1798 } else {
1800 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || 1799 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
1801 FLAG_smi_only_arrays); 1800 FLAG_smi_only_arrays);
1802 FastCloneShallowArrayStub::Mode mode = 1801 FastCloneShallowArrayStub::Mode mode =
1803 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; 1802 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
1804 1803
1805 if (has_fast_elements) { 1804 if (has_fast_elements) {
1806 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; 1805 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
(...skipping 23 matching lines...) Expand all
1830 if (IsFastObjectElementsKind(constant_elements_kind)) { 1829 if (IsFastObjectElementsKind(constant_elements_kind)) {
1831 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1830 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1832 __ Peek(x6, kPointerSize); // Copy of array literal. 1831 __ Peek(x6, kPointerSize); // Copy of array literal.
1833 __ Ldr(x1, FieldMemOperand(x6, JSObject::kElementsOffset)); 1832 __ Ldr(x1, FieldMemOperand(x6, JSObject::kElementsOffset));
1834 __ Str(result_register(), FieldMemOperand(x1, offset)); 1833 __ Str(result_register(), FieldMemOperand(x1, offset));
1835 // Update the write barrier for the array store. 1834 // Update the write barrier for the array store.
1836 __ RecordWriteField(x1, offset, result_register(), x10, 1835 __ RecordWriteField(x1, offset, result_register(), x10,
1837 kLRHasBeenSaved, kDontSaveFPRegs, 1836 kLRHasBeenSaved, kDontSaveFPRegs,
1838 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); 1837 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
1839 } else { 1838 } else {
1840 __ Mov(x3, Operand(Smi::FromInt(i))); 1839 __ Mov(x3, Smi::FromInt(i));
1841 StoreArrayLiteralElementStub stub; 1840 StoreArrayLiteralElementStub stub;
1842 __ CallStub(&stub); 1841 __ CallStub(&stub);
1843 } 1842 }
1844 1843
1845 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1844 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1846 } 1845 }
1847 1846
1848 if (result_saved) { 1847 if (result_saved) {
1849 __ Drop(1); // literal index 1848 __ Drop(1); // literal index
1850 context()->PlugTOS(); 1849 context()->PlugTOS();
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 int offset = Context::SlotOffset(var->index()); 2152 int offset = Context::SlotOffset(var->index());
2154 __ RecordWriteContextSlot( 2153 __ RecordWriteContextSlot(
2155 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); 2154 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs);
2156 } 2155 }
2157 } 2156 }
2158 2157
2159 2158
2160 void FullCodeGenerator::EmitCallStoreContextSlot( 2159 void FullCodeGenerator::EmitCallStoreContextSlot(
2161 Handle<String> name, StrictMode strict_mode) { 2160 Handle<String> name, StrictMode strict_mode) {
2162 __ Mov(x11, Operand(name)); 2161 __ Mov(x11, Operand(name));
2163 __ Mov(x10, Operand(Smi::FromInt(strict_mode))); 2162 __ Mov(x10, Smi::FromInt(strict_mode));
2164 // jssp[0] : mode. 2163 // jssp[0] : mode.
2165 // jssp[8] : name. 2164 // jssp[8] : name.
2166 // jssp[16] : context. 2165 // jssp[16] : context.
2167 // jssp[24] : value. 2166 // jssp[24] : value.
2168 __ Push(x0, cp, x11, x10); 2167 __ Push(x0, cp, x11, x10);
2169 __ CallRuntime(Runtime::kStoreContextSlot, 4); 2168 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2170 } 2169 }
2171 2170
2172 2171
2173 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2172 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 VisitForStackValue(args->at(i)); 2402 VisitForStackValue(args->at(i));
2404 } 2403 }
2405 } 2404 }
2406 // Record source position for debugger. 2405 // Record source position for debugger.
2407 SetSourcePosition(expr->position()); 2406 SetSourcePosition(expr->position());
2408 2407
2409 Handle<Object> uninitialized = 2408 Handle<Object> uninitialized =
2410 TypeFeedbackInfo::UninitializedSentinel(isolate()); 2409 TypeFeedbackInfo::UninitializedSentinel(isolate());
2411 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); 2410 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2412 __ LoadObject(x2, FeedbackVector()); 2411 __ LoadObject(x2, FeedbackVector());
2413 __ Mov(x3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); 2412 __ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot()));
2414 2413
2415 // Record call targets in unoptimized code. 2414 // Record call targets in unoptimized code.
2416 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2415 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2417 __ Peek(x1, (arg_count + 1) * kXRegSize); 2416 __ Peek(x1, (arg_count + 1) * kXRegSize);
2418 __ CallStub(&stub); 2417 __ CallStub(&stub);
2419 RecordJSReturnSite(expr); 2418 RecordJSReturnSite(expr);
2420 // Restore context register. 2419 // Restore context register.
2421 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2420 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2422 context()->DropAndPlug(1, x0); 2421 context()->DropAndPlug(1, x0);
2423 } 2422 }
(...skipping 10 matching lines...) Expand all
2434 } 2433 }
2435 2434
2436 // Prepare to push the receiver of the enclosing function. 2435 // Prepare to push the receiver of the enclosing function.
2437 int receiver_offset = 2 + info_->scope()->num_parameters(); 2436 int receiver_offset = 2 + info_->scope()->num_parameters();
2438 __ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize)); 2437 __ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize));
2439 2438
2440 // Push. 2439 // Push.
2441 __ Push(x10, x11); 2440 __ Push(x10, x11);
2442 2441
2443 // Prepare to push the language mode. 2442 // Prepare to push the language mode.
2444 __ Mov(x10, Operand(Smi::FromInt(strict_mode()))); 2443 __ Mov(x10, Smi::FromInt(strict_mode()));
2445 // Prepare to push the start position of the scope the calls resides in. 2444 // Prepare to push the start position of the scope the calls resides in.
2446 __ Mov(x11, Operand(Smi::FromInt(scope()->start_position()))); 2445 __ Mov(x11, Smi::FromInt(scope()->start_position()));
2447 2446
2448 // Push. 2447 // Push.
2449 __ Push(x10, x11); 2448 __ Push(x10, x11);
2450 2449
2451 // Do the runtime call. 2450 // Do the runtime call.
2452 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2451 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2453 } 2452 }
2454 2453
2455 2454
2456 void FullCodeGenerator::VisitCall(Call* expr) { 2455 void FullCodeGenerator::VisitCall(Call* expr) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 TypeFeedbackInfo::UninitializedSentinel(isolate()); 2608 TypeFeedbackInfo::UninitializedSentinel(isolate());
2610 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized); 2609 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2611 if (FLAG_pretenuring_call_new) { 2610 if (FLAG_pretenuring_call_new) {
2612 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), 2611 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
2613 isolate()->factory()->NewAllocationSite()); 2612 isolate()->factory()->NewAllocationSite());
2614 ASSERT(expr->AllocationSiteFeedbackSlot() == 2613 ASSERT(expr->AllocationSiteFeedbackSlot() ==
2615 expr->CallNewFeedbackSlot() + 1); 2614 expr->CallNewFeedbackSlot() + 1);
2616 } 2615 }
2617 2616
2618 __ LoadObject(x2, FeedbackVector()); 2617 __ LoadObject(x2, FeedbackVector());
2619 __ Mov(x3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2618 __ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot()));
2620 2619
2621 CallConstructStub stub(RECORD_CALL_TARGET); 2620 CallConstructStub stub(RECORD_CALL_TARGET);
2622 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2621 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2623 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2622 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2624 context()->Plug(x0); 2623 context()->Plug(x0);
2625 } 2624 }
2626 2625
2627 2626
2628 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2627 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2629 ZoneList<Expression*>* args = expr->arguments(); 2628 ZoneList<Expression*>* args = expr->arguments();
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 Label* fall_through = NULL; 2947 Label* fall_through = NULL;
2949 context()->PrepareTest(&materialize_true, &materialize_false, 2948 context()->PrepareTest(&materialize_true, &materialize_false,
2950 &if_true, &if_false, &fall_through); 2949 &if_true, &if_false, &fall_through);
2951 2950
2952 // Get the frame pointer for the calling frame. 2951 // Get the frame pointer for the calling frame.
2953 __ Ldr(x2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 2952 __ Ldr(x2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2954 2953
2955 // Skip the arguments adaptor frame if it exists. 2954 // Skip the arguments adaptor frame if it exists.
2956 Label check_frame_marker; 2955 Label check_frame_marker;
2957 __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kContextOffset)); 2956 __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kContextOffset));
2958 __ Cmp(x1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2957 __ Cmp(x1, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2959 __ B(ne, &check_frame_marker); 2958 __ B(ne, &check_frame_marker);
2960 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); 2959 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset));
2961 2960
2962 // Check the marker in the calling frame. 2961 // Check the marker in the calling frame.
2963 __ Bind(&check_frame_marker); 2962 __ Bind(&check_frame_marker);
2964 __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kMarkerOffset)); 2963 __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kMarkerOffset));
2965 __ Cmp(x1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 2964 __ Cmp(x1, Smi::FromInt(StackFrame::CONSTRUCT));
2966 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2965 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2967 Split(eq, if_true, if_false, fall_through); 2966 Split(eq, if_true, if_false, fall_through);
2968 2967
2969 context()->Plug(if_true, if_false); 2968 context()->Plug(if_true, if_false);
2970 } 2969 }
2971 2970
2972 2971
2973 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { 2972 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
2974 ZoneList<Expression*>* args = expr->arguments(); 2973 ZoneList<Expression*>* args = expr->arguments();
2975 ASSERT(args->length() == 2); 2974 ASSERT(args->length() == 2);
(...skipping 18 matching lines...) Expand all
2994 } 2993 }
2995 2994
2996 2995
2997 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { 2996 void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
2998 ZoneList<Expression*>* args = expr->arguments(); 2997 ZoneList<Expression*>* args = expr->arguments();
2999 ASSERT(args->length() == 1); 2998 ASSERT(args->length() == 1);
3000 2999
3001 // ArgumentsAccessStub expects the key in x1. 3000 // ArgumentsAccessStub expects the key in x1.
3002 VisitForAccumulatorValue(args->at(0)); 3001 VisitForAccumulatorValue(args->at(0));
3003 __ Mov(x1, x0); 3002 __ Mov(x1, x0);
3004 __ Mov(x0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); 3003 __ Mov(x0, Smi::FromInt(info_->scope()->num_parameters()));
3005 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 3004 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
3006 __ CallStub(&stub); 3005 __ CallStub(&stub);
3007 context()->Plug(x0); 3006 context()->Plug(x0);
3008 } 3007 }
3009 3008
3010 3009
3011 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { 3010 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
3012 ASSERT(expr->arguments()->length() == 0); 3011 ASSERT(expr->arguments()->length() == 0);
3013 Label exit; 3012 Label exit;
3014 // Get the number of formal parameters. 3013 // Get the number of formal parameters.
3015 __ Mov(x0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); 3014 __ Mov(x0, Smi::FromInt(info_->scope()->num_parameters()));
3016 3015
3017 // Check if the calling frame is an arguments adaptor frame. 3016 // Check if the calling frame is an arguments adaptor frame.
3018 __ Ldr(x12, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3017 __ Ldr(x12, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3019 __ Ldr(x13, MemOperand(x12, StandardFrameConstants::kContextOffset)); 3018 __ Ldr(x13, MemOperand(x12, StandardFrameConstants::kContextOffset));
3020 __ Cmp(x13, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3019 __ Cmp(x13, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3021 __ B(ne, &exit); 3020 __ B(ne, &exit);
3022 3021
3023 // Arguments adaptor case: Read the arguments length from the 3022 // Arguments adaptor case: Read the arguments length from the
3024 // adaptor frame. 3023 // adaptor frame.
3025 __ Ldr(x0, MemOperand(x12, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3024 __ Ldr(x0, MemOperand(x12, ArgumentsAdaptorFrameConstants::kLengthOffset));
3026 3025
3027 __ Bind(&exit); 3026 __ Bind(&exit);
3028 context()->Plug(x0); 3027 context()->Plug(x0);
3029 } 3028 }
3030 3029
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 3175
3177 __ JumpIfSmi(object, &not_date_object); 3176 __ JumpIfSmi(object, &not_date_object);
3178 __ JumpIfNotObjectType(object, x10, x10, JS_DATE_TYPE, &not_date_object); 3177 __ JumpIfNotObjectType(object, x10, x10, JS_DATE_TYPE, &not_date_object);
3179 3178
3180 if (index->value() == 0) { 3179 if (index->value() == 0) {
3181 __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset)); 3180 __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
3182 __ B(&done); 3181 __ B(&done);
3183 } else { 3182 } else {
3184 if (index->value() < JSDate::kFirstUncachedField) { 3183 if (index->value() < JSDate::kFirstUncachedField) {
3185 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 3184 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
3186 __ Mov(x10, Operand(stamp)); 3185 __ Mov(x10, stamp);
3187 __ Ldr(stamp_addr, MemOperand(x10)); 3186 __ Ldr(stamp_addr, MemOperand(x10));
3188 __ Ldr(stamp_cache, FieldMemOperand(object, JSDate::kCacheStampOffset)); 3187 __ Ldr(stamp_cache, FieldMemOperand(object, JSDate::kCacheStampOffset));
3189 __ Cmp(stamp_addr, stamp_cache); 3188 __ Cmp(stamp_addr, stamp_cache);
3190 __ B(ne, &runtime); 3189 __ B(ne, &runtime);
3191 __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset + 3190 __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset +
3192 kPointerSize * index->value())); 3191 kPointerSize * index->value()));
3193 __ B(&done); 3192 __ B(&done);
3194 } 3193 }
3195 3194
3196 __ Bind(&runtime); 3195 __ Bind(&runtime);
3197 __ Mov(x1, Operand(index)); 3196 __ Mov(x1, index);
3198 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 3197 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
3199 __ B(&done); 3198 __ B(&done);
3200 } 3199 }
3201 3200
3202 __ Bind(&not_date_object); 3201 __ Bind(&not_date_object);
3203 __ CallRuntime(Runtime::kThrowNotDateError, 0); 3202 __ CallRuntime(Runtime::kThrowNotDateError, 0);
3204 __ Bind(&done); 3203 __ Bind(&done);
3205 context()->Plug(x0); 3204 context()->Plug(x0);
3206 } 3205 }
3207 3206
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
3415 __ B(&done); 3414 __ B(&done);
3416 3415
3417 __ Bind(&index_out_of_range); 3416 __ Bind(&index_out_of_range);
3418 // When the index is out of range, the spec requires us to return 3417 // When the index is out of range, the spec requires us to return
3419 // the empty string. 3418 // the empty string.
3420 __ LoadRoot(result, Heap::kempty_stringRootIndex); 3419 __ LoadRoot(result, Heap::kempty_stringRootIndex);
3421 __ B(&done); 3420 __ B(&done);
3422 3421
3423 __ Bind(&need_conversion); 3422 __ Bind(&need_conversion);
3424 // Move smi zero into the result register, which will trigger conversion. 3423 // Move smi zero into the result register, which will trigger conversion.
3425 __ Mov(result, Operand(Smi::FromInt(0))); 3424 __ Mov(result, Smi::FromInt(0));
3426 __ B(&done); 3425 __ B(&done);
3427 3426
3428 NopRuntimeCallHelper call_helper; 3427 NopRuntimeCallHelper call_helper;
3429 generator.GenerateSlow(masm_, call_helper); 3428 generator.GenerateSlow(masm_, call_helper);
3430 3429
3431 __ Bind(&done); 3430 __ Bind(&done);
3432 context()->Plug(result); 3431 context()->Plug(result);
3433 } 3432 }
3434 3433
3435 3434
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3668 __ Add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2)); 3667 __ Add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
3669 // Loop condition: while (element < elements_end). 3668 // Loop condition: while (element < elements_end).
3670 // Live values in registers: 3669 // Live values in registers:
3671 // elements: Fixed array of strings. 3670 // elements: Fixed array of strings.
3672 // array_length: Length of the fixed array of strings (not smi) 3671 // array_length: Length of the fixed array of strings (not smi)
3673 // separator: Separator string 3672 // separator: Separator string
3674 // string_length: Accumulated sum of string lengths (not smi). 3673 // string_length: Accumulated sum of string lengths (not smi).
3675 // element: Current array element. 3674 // element: Current array element.
3676 // elements_end: Array end. 3675 // elements_end: Array end.
3677 if (FLAG_debug_code) { 3676 if (FLAG_debug_code) {
3678 __ Cmp(array_length, Operand(0)); 3677 __ Cmp(array_length, 0);
3679 __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); 3678 __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin);
3680 } 3679 }
3681 __ Bind(&loop); 3680 __ Bind(&loop);
3682 __ Ldr(string, MemOperand(element, kPointerSize, PostIndex)); 3681 __ Ldr(string, MemOperand(element, kPointerSize, PostIndex));
3683 __ JumpIfSmi(string, &bailout); 3682 __ JumpIfSmi(string, &bailout);
3684 __ Ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); 3683 __ Ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset));
3685 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 3684 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
3686 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); 3685 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout);
3687 __ Ldrsw(scratch1, 3686 __ Ldrsw(scratch1,
3688 UntagSmiFieldMemOperand(string, SeqOneByteString::kLengthOffset)); 3687 UntagSmiFieldMemOperand(string, SeqOneByteString::kLengthOffset));
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
3881 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3880 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3882 switch (expr->op()) { 3881 switch (expr->op()) {
3883 case Token::DELETE: { 3882 case Token::DELETE: {
3884 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3883 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3885 Property* property = expr->expression()->AsProperty(); 3884 Property* property = expr->expression()->AsProperty();
3886 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3885 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3887 3886
3888 if (property != NULL) { 3887 if (property != NULL) {
3889 VisitForStackValue(property->obj()); 3888 VisitForStackValue(property->obj());
3890 VisitForStackValue(property->key()); 3889 VisitForStackValue(property->key());
3891 __ Mov(x10, Operand(Smi::FromInt(strict_mode()))); 3890 __ Mov(x10, Smi::FromInt(strict_mode()));
3892 __ Push(x10); 3891 __ Push(x10);
3893 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3892 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3894 context()->Plug(x0); 3893 context()->Plug(x0);
3895 } else if (proxy != NULL) { 3894 } else if (proxy != NULL) {
3896 Variable* var = proxy->var(); 3895 Variable* var = proxy->var();
3897 // Delete of an unqualified identifier is disallowed in strict mode 3896 // Delete of an unqualified identifier is disallowed in strict mode
3898 // but "delete this" is allowed. 3897 // but "delete this" is allowed.
3899 ASSERT(strict_mode() == SLOPPY || var->is_this()); 3898 ASSERT(strict_mode() == SLOPPY || var->is_this());
3900 if (var->IsUnallocated()) { 3899 if (var->IsUnallocated()) {
3901 __ Ldr(x12, GlobalObjectMemOperand()); 3900 __ Ldr(x12, GlobalObjectMemOperand());
3902 __ Mov(x11, Operand(var->name())); 3901 __ Mov(x11, Operand(var->name()));
3903 __ Mov(x10, Operand(Smi::FromInt(SLOPPY))); 3902 __ Mov(x10, Smi::FromInt(SLOPPY));
3904 __ Push(x12, x11, x10); 3903 __ Push(x12, x11, x10);
3905 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3904 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3906 context()->Plug(x0); 3905 context()->Plug(x0);
3907 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3906 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3908 // Result of deleting non-global, non-dynamic variables is false. 3907 // Result of deleting non-global, non-dynamic variables is false.
3909 // The subexpression does not have side effects. 3908 // The subexpression does not have side effects.
3910 context()->Plug(var->is_this()); 3909 context()->Plug(var->is_this());
3911 } else { 3910 } else {
3912 // Non-global variable. Call the runtime to try to delete from the 3911 // Non-global variable. Call the runtime to try to delete from the
3913 // context where the variable was introduced. 3912 // context where the variable was introduced.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
4061 case NAMED_PROPERTY: 4060 case NAMED_PROPERTY:
4062 __ Poke(x0, kPointerSize); 4061 __ Poke(x0, kPointerSize);
4063 break; 4062 break;
4064 case KEYED_PROPERTY: 4063 case KEYED_PROPERTY:
4065 __ Poke(x0, kPointerSize * 2); 4064 __ Poke(x0, kPointerSize * 2);
4066 break; 4065 break;
4067 } 4066 }
4068 } 4067 }
4069 } 4068 }
4070 4069
4071 __ Adds(x0, x0, Operand(Smi::FromInt(count_value))); 4070 __ Adds(x0, x0, Smi::FromInt(count_value));
4072 __ B(vc, &done); 4071 __ B(vc, &done);
4073 // Call stub. Undo operation first. 4072 // Call stub. Undo operation first.
4074 __ Sub(x0, x0, Operand(Smi::FromInt(count_value))); 4073 __ Sub(x0, x0, Smi::FromInt(count_value));
4075 __ B(&stub_call); 4074 __ B(&stub_call);
4076 __ Bind(&slow); 4075 __ Bind(&slow);
4077 } 4076 }
4078 ToNumberStub convert_stub; 4077 ToNumberStub convert_stub;
4079 __ CallStub(&convert_stub); 4078 __ CallStub(&convert_stub);
4080 4079
4081 // Save result for postfix expressions. 4080 // Save result for postfix expressions.
4082 if (expr->is_postfix()) { 4081 if (expr->is_postfix()) {
4083 if (!context()->IsEffect()) { 4082 if (!context()->IsEffect()) {
4084 // Save the result on the stack. If we have a named or keyed property 4083 // Save the result on the stack. If we have a named or keyed property
4085 // we store the result under the receiver that is currently on top 4084 // we store the result under the receiver that is currently on top
4086 // of the stack. 4085 // of the stack.
4087 switch (assign_type) { 4086 switch (assign_type) {
4088 case VARIABLE: 4087 case VARIABLE:
4089 __ Push(x0); 4088 __ Push(x0);
4090 break; 4089 break;
4091 case NAMED_PROPERTY: 4090 case NAMED_PROPERTY:
4092 __ Poke(x0, kXRegSize); 4091 __ Poke(x0, kXRegSize);
4093 break; 4092 break;
4094 case KEYED_PROPERTY: 4093 case KEYED_PROPERTY:
4095 __ Poke(x0, 2 * kXRegSize); 4094 __ Poke(x0, 2 * kXRegSize);
4096 break; 4095 break;
4097 } 4096 }
4098 } 4097 }
4099 } 4098 }
4100 4099
4101 __ Bind(&stub_call); 4100 __ Bind(&stub_call);
4102 __ Mov(x1, x0); 4101 __ Mov(x1, x0);
4103 __ Mov(x0, Operand(Smi::FromInt(count_value))); 4102 __ Mov(x0, Smi::FromInt(count_value));
4104 4103
4105 // Record position before stub call. 4104 // Record position before stub call.
4106 SetSourcePosition(expr->position()); 4105 SetSourcePosition(expr->position());
4107 4106
4108 { 4107 {
4109 Assembler::BlockPoolsScope scope(masm_); 4108 Assembler::BlockPoolsScope scope(masm_);
4110 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); 4109 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
4111 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); 4110 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
4112 patch_site.EmitPatchInfo(); 4111 patch_site.EmitPatchInfo();
4113 } 4112 }
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
4427 4426
4428 // TODO(jbramley): This label is bound here because the following code 4427 // TODO(jbramley): This label is bound here because the following code
4429 // looks at its pos(). Is it possible to do something more efficient here, 4428 // looks at its pos(). Is it possible to do something more efficient here,
4430 // perhaps using Adr? 4429 // perhaps using Adr?
4431 __ Bind(&continuation); 4430 __ Bind(&continuation);
4432 __ B(&resume); 4431 __ B(&resume);
4433 4432
4434 __ Bind(&suspend); 4433 __ Bind(&suspend);
4435 VisitForAccumulatorValue(expr->generator_object()); 4434 VisitForAccumulatorValue(expr->generator_object());
4436 ASSERT((continuation.pos() > 0) && Smi::IsValid(continuation.pos())); 4435 ASSERT((continuation.pos() > 0) && Smi::IsValid(continuation.pos()));
4437 __ Mov(x1, Operand(Smi::FromInt(continuation.pos()))); 4436 __ Mov(x1, Smi::FromInt(continuation.pos()));
4438 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); 4437 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
4439 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); 4438 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
4440 __ Mov(x1, cp); 4439 __ Mov(x1, cp);
4441 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, 4440 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
4442 kLRHasBeenSaved, kDontSaveFPRegs); 4441 kLRHasBeenSaved, kDontSaveFPRegs);
4443 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); 4442 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset);
4444 __ Cmp(__ StackPointer(), x1); 4443 __ Cmp(__ StackPointer(), x1);
4445 __ B(eq, &post_runtime); 4444 __ B(eq, &post_runtime);
4446 __ Push(x0); // generator object 4445 __ Push(x0); // generator object
4447 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 4446 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4448 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4447 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4449 __ Bind(&post_runtime); 4448 __ Bind(&post_runtime);
4450 __ Pop(result_register()); 4449 __ Pop(result_register());
4451 EmitReturnSequence(); 4450 EmitReturnSequence();
4452 4451
4453 __ Bind(&resume); 4452 __ Bind(&resume);
4454 context()->Plug(result_register()); 4453 context()->Plug(result_register());
4455 break; 4454 break;
4456 } 4455 }
4457 4456
4458 case Yield::FINAL: { 4457 case Yield::FINAL: {
4459 VisitForAccumulatorValue(expr->generator_object()); 4458 VisitForAccumulatorValue(expr->generator_object());
4460 __ Mov(x1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 4459 __ Mov(x1, Smi::FromInt(JSGeneratorObject::kGeneratorClosed));
4461 __ Str(x1, FieldMemOperand(result_register(), 4460 __ Str(x1, FieldMemOperand(result_register(),
4462 JSGeneratorObject::kContinuationOffset)); 4461 JSGeneratorObject::kContinuationOffset));
4463 // Pop value from top-of-stack slot, box result into result register. 4462 // Pop value from top-of-stack slot, box result into result register.
4464 EmitCreateIteratorResult(true); 4463 EmitCreateIteratorResult(true);
4465 EmitUnwindBeforeReturn(); 4464 EmitUnwindBeforeReturn();
4466 EmitReturnSequence(); 4465 EmitReturnSequence();
4467 break; 4466 break;
4468 } 4467 }
4469 4468
4470 case Yield::DELEGATING: { 4469 case Yield::DELEGATING: {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4502 // looks at its pos(). Is it possible to do something more efficient here, 4501 // looks at its pos(). Is it possible to do something more efficient here,
4503 // perhaps using Adr? 4502 // perhaps using Adr?
4504 __ Bind(&l_continuation); 4503 __ Bind(&l_continuation);
4505 __ B(&l_resume); 4504 __ B(&l_resume);
4506 4505
4507 __ Bind(&l_suspend); 4506 __ Bind(&l_suspend);
4508 const int generator_object_depth = kPointerSize + handler_size; 4507 const int generator_object_depth = kPointerSize + handler_size;
4509 __ Peek(x0, generator_object_depth); 4508 __ Peek(x0, generator_object_depth);
4510 __ Push(x0); // g 4509 __ Push(x0); // g
4511 ASSERT((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos())); 4510 ASSERT((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos()));
4512 __ Mov(x1, Operand(Smi::FromInt(l_continuation.pos()))); 4511 __ Mov(x1, Smi::FromInt(l_continuation.pos()));
4513 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); 4512 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
4514 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); 4513 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
4515 __ Mov(x1, cp); 4514 __ Mov(x1, cp);
4516 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, 4515 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
4517 kLRHasBeenSaved, kDontSaveFPRegs); 4516 kLRHasBeenSaved, kDontSaveFPRegs);
4518 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 4517 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4519 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4518 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4520 __ Pop(x0); // result 4519 __ Pop(x0); // result
4521 EmitReturnSequence(); 4520 EmitReturnSequence();
4522 __ Bind(&l_resume); // received in x0 4521 __ Bind(&l_resume); // received in x0
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4580 VisitForStackValue(generator); 4579 VisitForStackValue(generator);
4581 VisitForAccumulatorValue(value); 4580 VisitForAccumulatorValue(value);
4582 __ Pop(generator_object); 4581 __ Pop(generator_object);
4583 4582
4584 // Check generator state. 4583 // Check generator state.
4585 Label wrong_state, closed_state, done; 4584 Label wrong_state, closed_state, done;
4586 __ Ldr(x10, FieldMemOperand(generator_object, 4585 __ Ldr(x10, FieldMemOperand(generator_object,
4587 JSGeneratorObject::kContinuationOffset)); 4586 JSGeneratorObject::kContinuationOffset));
4588 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); 4587 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
4589 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); 4588 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
4590 __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), eq, &closed_state); 4589 __ CompareAndBranch(x10, Smi::FromInt(0), eq, &closed_state);
4591 __ CompareAndBranch(x10, Operand(Smi::FromInt(0)), lt, &wrong_state); 4590 __ CompareAndBranch(x10, Smi::FromInt(0), lt, &wrong_state);
4592 4591
4593 // Load suspended function and context. 4592 // Load suspended function and context.
4594 __ Ldr(cp, FieldMemOperand(generator_object, 4593 __ Ldr(cp, FieldMemOperand(generator_object,
4595 JSGeneratorObject::kContextOffset)); 4594 JSGeneratorObject::kContextOffset));
4596 __ Ldr(function, FieldMemOperand(generator_object, 4595 __ Ldr(function, FieldMemOperand(generator_object,
4597 JSGeneratorObject::kFunctionOffset)); 4596 JSGeneratorObject::kFunctionOffset));
4598 4597
4599 // Load receiver and store as the first argument. 4598 // Load receiver and store as the first argument.
4600 __ Ldr(x10, FieldMemOperand(generator_object, 4599 __ Ldr(x10, FieldMemOperand(generator_object,
4601 JSGeneratorObject::kReceiverOffset)); 4600 JSGeneratorObject::kReceiverOffset));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4635 // If we are sending a value and there is no operand stack, we can jump back 4634 // If we are sending a value and there is no operand stack, we can jump back
4636 // in directly. 4635 // in directly.
4637 if (resume_mode == JSGeneratorObject::NEXT) { 4636 if (resume_mode == JSGeneratorObject::NEXT) {
4638 Label slow_resume; 4637 Label slow_resume;
4639 __ Cbnz(operand_stack_size, &slow_resume); 4638 __ Cbnz(operand_stack_size, &slow_resume);
4640 __ Ldr(x10, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); 4639 __ Ldr(x10, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
4641 __ Ldrsw(x11, 4640 __ Ldrsw(x11,
4642 UntagSmiFieldMemOperand(generator_object, 4641 UntagSmiFieldMemOperand(generator_object,
4643 JSGeneratorObject::kContinuationOffset)); 4642 JSGeneratorObject::kContinuationOffset));
4644 __ Add(x10, x10, x11); 4643 __ Add(x10, x10, x11);
4645 __ Mov(x12, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); 4644 __ Mov(x12, Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
4646 __ Str(x12, FieldMemOperand(generator_object, 4645 __ Str(x12, FieldMemOperand(generator_object,
4647 JSGeneratorObject::kContinuationOffset)); 4646 JSGeneratorObject::kContinuationOffset));
4648 __ Br(x10); 4647 __ Br(x10);
4649 4648
4650 __ Bind(&slow_resume); 4649 __ Bind(&slow_resume);
4651 } 4650 }
4652 4651
4653 // Otherwise, we push holes for the operand stack and call the runtime to fix 4652 // Otherwise, we push holes for the operand stack and call the runtime to fix
4654 // up the stack and the handlers. 4653 // up the stack and the handlers.
4655 __ PushMultipleTimes(the_hole, operand_stack_size); 4654 __ PushMultipleTimes(the_hole, operand_stack_size);
4656 4655
4657 __ Mov(x10, Operand(Smi::FromInt(resume_mode))); 4656 __ Mov(x10, Smi::FromInt(resume_mode));
4658 __ Push(generator_object, result_register(), x10); 4657 __ Push(generator_object, result_register(), x10);
4659 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 4658 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
4660 // Not reached: the runtime call returns elsewhere. 4659 // Not reached: the runtime call returns elsewhere.
4661 __ Unreachable(); 4660 __ Unreachable();
4662 4661
4663 // Reach here when generator is closed. 4662 // Reach here when generator is closed.
4664 __ Bind(&closed_state); 4663 __ Bind(&closed_state);
4665 if (resume_mode == JSGeneratorObject::NEXT) { 4664 if (resume_mode == JSGeneratorObject::NEXT) {
4666 // Return completed iterator result when generator is closed. 4665 // Return completed iterator result when generator is closed.
4667 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); 4666 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
4791 ASSERT(!result_register().is(x10)); 4790 ASSERT(!result_register().is(x10));
4792 // Preserve the result register while executing finally block. 4791 // Preserve the result register while executing finally block.
4793 // Also cook the return address in lr to the stack (smi encoded Code* delta). 4792 // Also cook the return address in lr to the stack (smi encoded Code* delta).
4794 __ Sub(x10, lr, Operand(masm_->CodeObject())); 4793 __ Sub(x10, lr, Operand(masm_->CodeObject()));
4795 __ SmiTag(x10); 4794 __ SmiTag(x10);
4796 __ Push(result_register(), x10); 4795 __ Push(result_register(), x10);
4797 4796
4798 // Store pending message while executing finally block. 4797 // Store pending message while executing finally block.
4799 ExternalReference pending_message_obj = 4798 ExternalReference pending_message_obj =
4800 ExternalReference::address_of_pending_message_obj(isolate()); 4799 ExternalReference::address_of_pending_message_obj(isolate());
4801 __ Mov(x10, Operand(pending_message_obj)); 4800 __ Mov(x10, pending_message_obj);
4802 __ Ldr(x10, MemOperand(x10)); 4801 __ Ldr(x10, MemOperand(x10));
4803 4802
4804 ExternalReference has_pending_message = 4803 ExternalReference has_pending_message =
4805 ExternalReference::address_of_has_pending_message(isolate()); 4804 ExternalReference::address_of_has_pending_message(isolate());
4806 __ Mov(x11, Operand(has_pending_message)); 4805 __ Mov(x11, has_pending_message);
4807 __ Ldr(x11, MemOperand(x11)); 4806 __ Ldr(x11, MemOperand(x11));
4808 __ SmiTag(x11); 4807 __ SmiTag(x11);
4809 4808
4810 __ Push(x10, x11); 4809 __ Push(x10, x11);
4811 4810
4812 ExternalReference pending_message_script = 4811 ExternalReference pending_message_script =
4813 ExternalReference::address_of_pending_message_script(isolate()); 4812 ExternalReference::address_of_pending_message_script(isolate());
4814 __ Mov(x10, Operand(pending_message_script)); 4813 __ Mov(x10, pending_message_script);
4815 __ Ldr(x10, MemOperand(x10)); 4814 __ Ldr(x10, MemOperand(x10));
4816 __ Push(x10); 4815 __ Push(x10);
4817 } 4816 }
4818 4817
4819 4818
4820 void FullCodeGenerator::ExitFinallyBlock() { 4819 void FullCodeGenerator::ExitFinallyBlock() {
4821 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock"); 4820 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock");
4822 ASSERT(!result_register().is(x10)); 4821 ASSERT(!result_register().is(x10));
4823 4822
4824 // Restore pending message from stack. 4823 // Restore pending message from stack.
4825 __ Pop(x10, x11, x12); 4824 __ Pop(x10, x11, x12);
4826 ExternalReference pending_message_script = 4825 ExternalReference pending_message_script =
4827 ExternalReference::address_of_pending_message_script(isolate()); 4826 ExternalReference::address_of_pending_message_script(isolate());
4828 __ Mov(x13, Operand(pending_message_script)); 4827 __ Mov(x13, pending_message_script);
4829 __ Str(x10, MemOperand(x13)); 4828 __ Str(x10, MemOperand(x13));
4830 4829
4831 __ SmiUntag(x11); 4830 __ SmiUntag(x11);
4832 ExternalReference has_pending_message = 4831 ExternalReference has_pending_message =
4833 ExternalReference::address_of_has_pending_message(isolate()); 4832 ExternalReference::address_of_has_pending_message(isolate());
4834 __ Mov(x13, Operand(has_pending_message)); 4833 __ Mov(x13, has_pending_message);
4835 __ Str(x11, MemOperand(x13)); 4834 __ Str(x11, MemOperand(x13));
4836 4835
4837 ExternalReference pending_message_obj = 4836 ExternalReference pending_message_obj =
4838 ExternalReference::address_of_pending_message_obj(isolate()); 4837 ExternalReference::address_of_pending_message_obj(isolate());
4839 __ Mov(x13, Operand(pending_message_obj)); 4838 __ Mov(x13, pending_message_obj);
4840 __ Str(x12, MemOperand(x13)); 4839 __ Str(x12, MemOperand(x13));
4841 4840
4842 // Restore result register and cooked return address from the stack. 4841 // Restore result register and cooked return address from the stack.
4843 __ Pop(x10, result_register()); 4842 __ Pop(x10, result_register());
4844 4843
4845 // Uncook the return address (see EnterFinallyBlock). 4844 // Uncook the return address (see EnterFinallyBlock).
4846 __ SmiUntag(x10); 4845 __ SmiUntag(x10);
4847 __ Add(x11, x10, Operand(masm_->CodeObject())); 4846 __ Add(x11, x10, Operand(masm_->CodeObject()));
4848 __ Br(x11); 4847 __ Br(x11);
4849 } 4848 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
4973 return previous_; 4972 return previous_;
4974 } 4973 }
4975 4974
4976 4975
4977 #undef __ 4976 #undef __
4978 4977
4979 4978
4980 } } // namespace v8::internal 4979 } } // namespace v8::internal
4981 4980
4982 #endif // V8_TARGET_ARCH_A64 4981 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/deoptimizer-a64.cc ('k') | src/a64/ic-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698