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

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

Issue 901083004: Contribution of PowerPC port (continuation of 422063005) - PPC dir update (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Contribution of PowerPC port (continuation of 422063005) - PPC dir update -comments and rebase Created 5 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
« no previous file with comments | « src/ppc/disasm-ppc.cc ('k') | src/ppc/interface-descriptors-ppc.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 #ifdef DEBUG 116 #ifdef DEBUG
117 if (strlen(FLAG_stop_at) > 0 && 117 if (strlen(FLAG_stop_at) > 0 &&
118 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 118 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
119 __ stop("stop-at"); 119 __ stop("stop-at");
120 } 120 }
121 #endif 121 #endif
122 122
123 // Sloppy mode functions and builtins need to replace the receiver with the 123 // Sloppy mode functions and builtins need to replace the receiver with the
124 // global proxy when called as functions (without an explicit receiver 124 // global proxy when called as functions (without an explicit receiver
125 // object). 125 // object).
126 if (info->strict_mode() == SLOPPY && !info->is_native()) { 126 if (is_sloppy(info->language_mode()) && !info->is_native()) {
127 Label ok; 127 Label ok;
128 int receiver_offset = info->scope()->num_parameters() * kPointerSize; 128 int receiver_offset = info->scope()->num_parameters() * kPointerSize;
129 __ LoadP(r5, MemOperand(sp, receiver_offset), r0); 129 __ LoadP(r5, MemOperand(sp, receiver_offset), r0);
130 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex); 130 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex);
131 __ bne(&ok); 131 __ bne(&ok);
132 132
133 __ LoadP(r5, GlobalObjectOperand()); 133 __ LoadP(r5, GlobalObjectOperand());
134 __ LoadP(r5, FieldMemOperand(r5, GlobalObject::kGlobalProxyOffset)); 134 __ LoadP(r5, FieldMemOperand(r5, GlobalObject::kGlobalProxyOffset));
135 135
136 __ StoreP(r5, MemOperand(sp, receiver_offset), r0); 136 __ StoreP(r5, MemOperand(sp, receiver_offset), r0);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 int offset = num_parameters * kPointerSize; 260 int offset = num_parameters * kPointerSize;
261 __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset)); 261 __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset));
262 __ LoadSmiLiteral(r4, Smi::FromInt(num_parameters)); 262 __ LoadSmiLiteral(r4, Smi::FromInt(num_parameters));
263 __ Push(r6, r5, r4); 263 __ Push(r6, r5, r4);
264 264
265 // Arguments to ArgumentsAccessStub: 265 // Arguments to ArgumentsAccessStub:
266 // function, receiver address, parameter count. 266 // function, receiver address, parameter count.
267 // The stub will rewrite receiever and parameter count if the previous 267 // The stub will rewrite receiever and parameter count if the previous
268 // stack frame was an arguments adapter frame. 268 // stack frame was an arguments adapter frame.
269 ArgumentsAccessStub::Type type; 269 ArgumentsAccessStub::Type type;
270 if (strict_mode() == STRICT) { 270 if (is_strict(language_mode())) {
271 type = ArgumentsAccessStub::NEW_STRICT; 271 type = ArgumentsAccessStub::NEW_STRICT;
272 } else if (function()->has_duplicate_parameters()) { 272 } else if (function()->has_duplicate_parameters()) {
273 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 273 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
274 } else { 274 } else {
275 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 275 type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
276 } 276 }
277 ArgumentsAccessStub stub(isolate(), type); 277 ArgumentsAccessStub stub(isolate(), type);
278 __ CallStub(&stub); 278 __ CallStub(&stub);
279 279
280 SetVar(arguments, r3, r4, r5); 280 SetVar(arguments, r3, r4, r5);
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 Comment cmnt(masm_, "[ ForInStatement"); 1059 Comment cmnt(masm_, "[ ForInStatement");
1060 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1060 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
1061 SetStatementPosition(stmt); 1061 SetStatementPosition(stmt);
1062 1062
1063 Label loop, exit; 1063 Label loop, exit;
1064 ForIn loop_statement(this, stmt); 1064 ForIn loop_statement(this, stmt);
1065 increment_loop_depth(); 1065 increment_loop_depth();
1066 1066
1067 // Get the object to enumerate over. If the object is null or undefined, skip 1067 // Get the object to enumerate over. If the object is null or undefined, skip
1068 // over the loop. See ECMA-262 version 5, section 12.6.4. 1068 // over the loop. See ECMA-262 version 5, section 12.6.4.
1069 SetExpressionPosition(stmt->enumerable());
1069 VisitForAccumulatorValue(stmt->enumerable()); 1070 VisitForAccumulatorValue(stmt->enumerable());
1070 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1071 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1071 __ cmp(r3, ip); 1072 __ cmp(r3, ip);
1072 __ beq(&exit); 1073 __ beq(&exit);
1073 Register null_value = r7; 1074 Register null_value = r7;
1074 __ LoadRoot(null_value, Heap::kNullValueRootIndex); 1075 __ LoadRoot(null_value, Heap::kNullValueRootIndex);
1075 __ cmp(r3, null_value); 1076 __ cmp(r3, null_value);
1076 __ beq(&exit); 1077 __ beq(&exit);
1077 1078
1078 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); 1079 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy 1165 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy
1165 __ bind(&non_proxy); 1166 __ bind(&non_proxy);
1166 __ Push(r4, r3); // Smi and array 1167 __ Push(r4, r3); // Smi and array
1167 __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset)); 1168 __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset));
1168 __ LoadSmiLiteral(r3, Smi::FromInt(0)); 1169 __ LoadSmiLiteral(r3, Smi::FromInt(0));
1169 __ Push(r4, r3); // Fixed array length (as smi) and initial index. 1170 __ Push(r4, r3); // Fixed array length (as smi) and initial index.
1170 1171
1171 // Generate code for doing the condition check. 1172 // Generate code for doing the condition check.
1172 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1173 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1173 __ bind(&loop); 1174 __ bind(&loop);
1175 SetExpressionPosition(stmt->each());
1176
1174 // Load the current count to r3, load the length to r4. 1177 // Load the current count to r3, load the length to r4.
1175 __ LoadP(r3, MemOperand(sp, 0 * kPointerSize)); 1178 __ LoadP(r3, MemOperand(sp, 0 * kPointerSize));
1176 __ LoadP(r4, MemOperand(sp, 1 * kPointerSize)); 1179 __ LoadP(r4, MemOperand(sp, 1 * kPointerSize));
1177 __ cmpl(r3, r4); // Compare to the array length. 1180 __ cmpl(r3, r4); // Compare to the array length.
1178 __ bge(loop_statement.break_label()); 1181 __ bge(loop_statement.break_label());
1179 1182
1180 // Get the current entry of the array into register r6. 1183 // Get the current entry of the array into register r6.
1181 __ LoadP(r5, MemOperand(sp, 2 * kPointerSize)); 1184 __ LoadP(r5, MemOperand(sp, 2 * kPointerSize));
1182 __ addi(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 1185 __ addi(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1183 __ SmiToPtrArrayOffset(r6, r3); 1186 __ SmiToPtrArrayOffset(r6, r3);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 __ bind(loop_statement.break_label()); 1240 __ bind(loop_statement.break_label());
1238 __ Drop(5); 1241 __ Drop(5);
1239 1242
1240 // Exit and decrement the loop depth. 1243 // Exit and decrement the loop depth.
1241 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1244 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1242 __ bind(&exit); 1245 __ bind(&exit);
1243 decrement_loop_depth(); 1246 decrement_loop_depth();
1244 } 1247 }
1245 1248
1246 1249
1247 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1248 Comment cmnt(masm_, "[ ForOfStatement");
1249 SetStatementPosition(stmt);
1250
1251 Iteration loop_statement(this, stmt);
1252 increment_loop_depth();
1253
1254 // var iterator = iterable[Symbol.iterator]();
1255 VisitForEffect(stmt->assign_iterator());
1256
1257 // Loop entry.
1258 __ bind(loop_statement.continue_label());
1259
1260 // result = iterator.next()
1261 VisitForEffect(stmt->next_result());
1262
1263 // if (result.done) break;
1264 Label result_not_done;
1265 VisitForControl(stmt->result_done(), loop_statement.break_label(),
1266 &result_not_done, &result_not_done);
1267 __ bind(&result_not_done);
1268
1269 // each = result.value
1270 VisitForEffect(stmt->assign_each());
1271
1272 // Generate code for the body of the loop.
1273 Visit(stmt->body());
1274
1275 // Check stack before looping.
1276 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1277 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
1278 __ b(loop_statement.continue_label());
1279
1280 // Exit and decrement the loop depth.
1281 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1282 __ bind(loop_statement.break_label());
1283 decrement_loop_depth();
1284 }
1285
1286
1287 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1250 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1288 bool pretenure) { 1251 bool pretenure) {
1289 // Use the fast case closure allocation code that allocates in new 1252 // Use the fast case closure allocation code that allocates in new
1290 // space for nested functions that don't need literals cloning. If 1253 // space for nested functions that don't need literals cloning. If
1291 // we're running with the --always-opt or the --prepare-always-opt 1254 // we're running with the --always-opt or the --prepare-always-opt
1292 // flag, we need to use the runtime function so that the new function 1255 // flag, we need to use the runtime function so that the new function
1293 // we are creating here gets a chance to have its code optimized and 1256 // we are creating here gets a chance to have its code optimized and
1294 // doesn't just get a copy of the existing unoptimized code. 1257 // doesn't just get a copy of the existing unoptimized code.
1295 if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure && 1258 if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
1296 scope()->is_function_scope() && info->num_literals() == 0) { 1259 scope()->is_function_scope() && info->num_literals() == 0) {
1297 FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind()); 1260 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1298 __ mov(r5, Operand(info)); 1261 __ mov(r5, Operand(info));
1299 __ CallStub(&stub); 1262 __ CallStub(&stub);
1300 } else { 1263 } else {
1301 __ mov(r3, Operand(info)); 1264 __ mov(r3, Operand(info));
1302 __ LoadRoot( 1265 __ LoadRoot(
1303 r4, pretenure ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); 1266 r4, pretenure ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
1304 __ Push(cp, r3, r4); 1267 __ Push(cp, r3, r4);
1305 __ CallRuntime(Runtime::kNewClosure, 3); 1268 __ CallRuntime(Runtime::kNewClosure, 3);
1306 } 1269 }
1307 context()->Plug(r3); 1270 context()->Plug(r3);
(...skipping 24 matching lines...) Expand all
1332 } 1295 }
1333 1296
1334 __ Cmpi(r3, Operand(isolate()->factory()->undefined_value()), r0); 1297 __ Cmpi(r3, Operand(isolate()->factory()->undefined_value()), r0);
1335 Label done; 1298 Label done;
1336 __ bne(&done); 1299 __ bne(&done);
1337 __ CallRuntime(Runtime::kThrowNonMethodError, 0); 1300 __ CallRuntime(Runtime::kThrowNonMethodError, 0);
1338 __ bind(&done); 1301 __ bind(&done);
1339 } 1302 }
1340 1303
1341 1304
1305 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
1306 int offset) {
1307 if (NeedsHomeObject(initializer)) {
1308 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1309 __ mov(StoreDescriptor::NameRegister(),
1310 Operand(isolate()->factory()->home_object_symbol()));
1311 __ LoadP(StoreDescriptor::ValueRegister(),
1312 MemOperand(sp, offset * kPointerSize));
1313 CallStoreIC();
1314 }
1315 }
1316
1317
1342 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1318 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1343 TypeofState typeof_state, 1319 TypeofState typeof_state,
1344 Label* slow) { 1320 Label* slow) {
1345 Register current = cp; 1321 Register current = cp;
1346 Register next = r4; 1322 Register next = r4;
1347 Register temp = r5; 1323 Register temp = r5;
1348 1324
1349 Scope* s = scope(); 1325 Scope* s = scope();
1350 while (s != NULL) { 1326 while (s != NULL) {
1351 if (s->num_heap_slots() > 0) { 1327 if (s->num_heap_slots() > 0) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 // if (false) { const x; }; var y = x; 1486 // if (false) { const x; }; var y = x;
1511 // 1487 //
1512 // The condition on the declaration scopes is a conservative check for 1488 // The condition on the declaration scopes is a conservative check for
1513 // nested functions that access a binding and are called before the 1489 // nested functions that access a binding and are called before the
1514 // binding is initialized: 1490 // binding is initialized:
1515 // function() { f(); let x = 1; function f() { x = 2; } } 1491 // function() { f(); let x = 1; function f() { x = 2; } }
1516 // 1492 //
1517 bool skip_init_check; 1493 bool skip_init_check;
1518 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1494 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1519 skip_init_check = false; 1495 skip_init_check = false;
1496 } else if (var->is_this()) {
1497 CHECK(info_->function() != nullptr &&
1498 (info_->function()->kind() & kSubclassConstructor) != 0);
1499 // TODO(dslomov): implement 'this' hole check elimination.
1500 skip_init_check = false;
1520 } else { 1501 } else {
1521 // Check that we always have valid source position. 1502 // Check that we always have valid source position.
1522 DCHECK(var->initializer_position() != RelocInfo::kNoPosition); 1503 DCHECK(var->initializer_position() != RelocInfo::kNoPosition);
1523 DCHECK(proxy->position() != RelocInfo::kNoPosition); 1504 DCHECK(proxy->position() != RelocInfo::kNoPosition);
1524 skip_init_check = var->mode() != CONST_LEGACY && 1505 skip_init_check = var->mode() != CONST_LEGACY &&
1525 var->initializer_position() < proxy->position(); 1506 var->initializer_position() < proxy->position();
1526 } 1507 }
1527 1508
1528 if (!skip_init_check) { 1509 if (!skip_init_check) {
1529 Label done; 1510 Label done;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 // If result_saved is true the result is on top of the stack. If 1638 // If result_saved is true the result is on top of the stack. If
1658 // result_saved is false the result is in r3. 1639 // result_saved is false the result is in r3.
1659 bool result_saved = false; 1640 bool result_saved = false;
1660 1641
1661 // Mark all computed expressions that are bound to a key that 1642 // Mark all computed expressions that are bound to a key that
1662 // is shadowed by a later occurrence of the same key. For the 1643 // is shadowed by a later occurrence of the same key. For the
1663 // marked expressions, no store code is emitted. 1644 // marked expressions, no store code is emitted.
1664 expr->CalculateEmitStore(zone()); 1645 expr->CalculateEmitStore(zone());
1665 1646
1666 AccessorTable accessor_table(zone()); 1647 AccessorTable accessor_table(zone());
1667 for (int i = 0; i < expr->properties()->length(); i++) { 1648 int property_index = 0;
1668 ObjectLiteral::Property* property = expr->properties()->at(i); 1649 for (; property_index < expr->properties()->length(); property_index++) {
1650 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1651 if (property->is_computed_name()) break;
1669 if (property->IsCompileTimeValue()) continue; 1652 if (property->IsCompileTimeValue()) continue;
1670 1653
1671 Literal* key = property->key(); 1654 Literal* key = property->key()->AsLiteral();
1672 Expression* value = property->value(); 1655 Expression* value = property->value();
1673 if (!result_saved) { 1656 if (!result_saved) {
1674 __ push(r3); // Save result on stack 1657 __ push(r3); // Save result on stack
1675 result_saved = true; 1658 result_saved = true;
1676 } 1659 }
1677 switch (property->kind()) { 1660 switch (property->kind()) {
1678 case ObjectLiteral::Property::CONSTANT: 1661 case ObjectLiteral::Property::CONSTANT:
1679 UNREACHABLE(); 1662 UNREACHABLE();
1680 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1663 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1681 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1664 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1682 // Fall through. 1665 // Fall through.
1683 case ObjectLiteral::Property::COMPUTED: 1666 case ObjectLiteral::Property::COMPUTED:
1684 // It is safe to use [[Put]] here because the boilerplate already 1667 // It is safe to use [[Put]] here because the boilerplate already
1685 // contains computed properties with an uninitialized value. 1668 // contains computed properties with an uninitialized value.
1686 if (key->value()->IsInternalizedString()) { 1669 if (key->value()->IsInternalizedString()) {
1687 if (property->emit_store()) { 1670 if (property->emit_store()) {
1688 VisitForAccumulatorValue(value); 1671 VisitForAccumulatorValue(value);
1689 DCHECK(StoreDescriptor::ValueRegister().is(r3)); 1672 DCHECK(StoreDescriptor::ValueRegister().is(r3));
1690 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1673 __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1691 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1674 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1692 CallStoreIC(key->LiteralFeedbackId()); 1675 CallStoreIC(key->LiteralFeedbackId());
1693 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1676 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1677
1678 if (NeedsHomeObject(value)) {
1679 __ Move(StoreDescriptor::ReceiverRegister(), r3);
1680 __ mov(StoreDescriptor::NameRegister(),
1681 Operand(isolate()->factory()->home_object_symbol()));
1682 __ LoadP(StoreDescriptor::ValueRegister(), MemOperand(sp));
1683 CallStoreIC();
1684 }
1694 } else { 1685 } else {
1695 VisitForEffect(value); 1686 VisitForEffect(value);
1696 } 1687 }
1697 break; 1688 break;
1698 } 1689 }
1699 // Duplicate receiver on stack. 1690 // Duplicate receiver on stack.
1700 __ LoadP(r3, MemOperand(sp)); 1691 __ LoadP(r3, MemOperand(sp));
1701 __ push(r3); 1692 __ push(r3);
1702 VisitForStackValue(key); 1693 VisitForStackValue(key);
1703 VisitForStackValue(value); 1694 VisitForStackValue(value);
1704 if (property->emit_store()) { 1695 if (property->emit_store()) {
1696 EmitSetHomeObjectIfNeeded(value, 2);
1705 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes 1697 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes
1706 __ push(r3); 1698 __ push(r3);
1707 __ CallRuntime(Runtime::kSetProperty, 4); 1699 __ CallRuntime(Runtime::kSetProperty, 4);
1708 } else { 1700 } else {
1709 __ Drop(3); 1701 __ Drop(3);
1710 } 1702 }
1711 break; 1703 break;
1712 case ObjectLiteral::Property::PROTOTYPE: 1704 case ObjectLiteral::Property::PROTOTYPE:
1713 // Duplicate receiver on stack. 1705 // Duplicate receiver on stack.
1714 __ LoadP(r3, MemOperand(sp)); 1706 __ LoadP(r3, MemOperand(sp));
(...skipping 16 matching lines...) Expand all
1731 } 1723 }
1732 1724
1733 // Emit code to define accessors, using only a single call to the runtime for 1725 // Emit code to define accessors, using only a single call to the runtime for
1734 // each pair of corresponding getters and setters. 1726 // each pair of corresponding getters and setters.
1735 for (AccessorTable::Iterator it = accessor_table.begin(); 1727 for (AccessorTable::Iterator it = accessor_table.begin();
1736 it != accessor_table.end(); ++it) { 1728 it != accessor_table.end(); ++it) {
1737 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. 1729 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
1738 __ push(r3); 1730 __ push(r3);
1739 VisitForStackValue(it->first); 1731 VisitForStackValue(it->first);
1740 EmitAccessor(it->second->getter); 1732 EmitAccessor(it->second->getter);
1733 EmitSetHomeObjectIfNeeded(it->second->getter, 2);
1741 EmitAccessor(it->second->setter); 1734 EmitAccessor(it->second->setter);
1735 EmitSetHomeObjectIfNeeded(it->second->setter, 3);
1742 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); 1736 __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
1743 __ push(r3); 1737 __ push(r3);
1744 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1738 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1745 } 1739 }
1746 1740
1741 // Object literals have two parts. The "static" part on the left contains no
1742 // computed property names, and so we can compute its map ahead of time; see
1743 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1744 // starts with the first computed property name, and continues with all
1745 // properties to its right. All the code from above initializes the static
1746 // component of the object literal, and arranges for the map of the result to
1747 // reflect the static order in which the keys appear. For the dynamic
1748 // properties, we compile them into a series of "SetOwnProperty" runtime
1749 // calls. This will preserve insertion order.
1750 for (; property_index < expr->properties()->length(); property_index++) {
1751 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1752
1753 Expression* value = property->value();
1754 if (!result_saved) {
1755 __ push(r3); // Save result on the stack
1756 result_saved = true;
1757 }
1758
1759 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
1760 __ push(r3);
1761
1762 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1763 DCHECK(!property->is_computed_name());
1764 VisitForStackValue(value);
1765 DCHECK(property->emit_store());
1766 __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1767 } else {
1768 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1769 VisitForStackValue(value);
1770
1771 switch (property->kind()) {
1772 case ObjectLiteral::Property::CONSTANT:
1773 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1774 case ObjectLiteral::Property::COMPUTED:
1775 if (property->emit_store()) {
1776 __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
1777 __ push(r3);
1778 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1779 } else {
1780 __ Drop(3);
1781 }
1782 break;
1783
1784 case ObjectLiteral::Property::PROTOTYPE:
1785 UNREACHABLE();
1786 break;
1787
1788 case ObjectLiteral::Property::GETTER:
1789 __ mov(r3, Operand(Smi::FromInt(NONE)));
1790 __ push(r3);
1791 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4);
1792 break;
1793
1794 case ObjectLiteral::Property::SETTER:
1795 __ mov(r3, Operand(Smi::FromInt(NONE)));
1796 __ push(r3);
1797 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4);
1798 break;
1799 }
1800 }
1801 }
1802
1747 if (expr->has_function()) { 1803 if (expr->has_function()) {
1748 DCHECK(result_saved); 1804 DCHECK(result_saved);
1749 __ LoadP(r3, MemOperand(sp)); 1805 __ LoadP(r3, MemOperand(sp));
1750 __ push(r3); 1806 __ push(r3);
1751 __ CallRuntime(Runtime::kToFastProperties, 1); 1807 __ CallRuntime(Runtime::kToFastProperties, 1);
1752 } 1808 }
1753 1809
1754 if (result_saved) { 1810 if (result_saved) {
1755 context()->PlugTOS(); 1811 context()->PlugTOS();
1756 } else { 1812 } else {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 EmitKeyedPropertyLoad(property); 1983 EmitKeyedPropertyLoad(property);
1928 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1984 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1929 break; 1985 break;
1930 } 1986 }
1931 } 1987 }
1932 1988
1933 Token::Value op = expr->binary_op(); 1989 Token::Value op = expr->binary_op();
1934 __ push(r3); // Left operand goes on the stack. 1990 __ push(r3); // Left operand goes on the stack.
1935 VisitForAccumulatorValue(expr->value()); 1991 VisitForAccumulatorValue(expr->value());
1936 1992
1937 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1938 ? OVERWRITE_RIGHT
1939 : NO_OVERWRITE;
1940 SetSourcePosition(expr->position() + 1); 1993 SetSourcePosition(expr->position() + 1);
1941 AccumulatorValueContext context(this); 1994 AccumulatorValueContext context(this);
1942 if (ShouldInlineSmiCase(op)) { 1995 if (ShouldInlineSmiCase(op)) {
1943 EmitInlineSmiBinaryOp(expr->binary_operation(), op, mode, expr->target(), 1996 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(),
1944 expr->value()); 1997 expr->value());
1945 } else { 1998 } else {
1946 EmitBinaryOp(expr->binary_operation(), op, mode); 1999 EmitBinaryOp(expr->binary_operation(), op);
1947 } 2000 }
1948 2001
1949 // Deoptimization point in case the binary operation may have side effects. 2002 // Deoptimization point in case the binary operation may have side effects.
1950 PrepareForBailout(expr->binary_operation(), TOS_REG); 2003 PrepareForBailout(expr->binary_operation(), TOS_REG);
1951 } else { 2004 } else {
1952 VisitForAccumulatorValue(expr->value()); 2005 VisitForAccumulatorValue(expr->value());
1953 } 2006 }
1954 2007
1955 // Record source position before possible IC call. 2008 // Record source position before possible IC call.
1956 SetSourcePosition(expr->position()); 2009 SetSourcePosition(expr->position());
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 Expression* generator, Expression* value, 2205 Expression* generator, Expression* value,
2153 JSGeneratorObject::ResumeMode resume_mode) { 2206 JSGeneratorObject::ResumeMode resume_mode) {
2154 // The value stays in r3, and is ultimately read by the resumed generator, as 2207 // The value stays in r3, and is ultimately read by the resumed generator, as
2155 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 2208 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
2156 // is read to throw the value when the resumed generator is already closed. 2209 // is read to throw the value when the resumed generator is already closed.
2157 // r4 will hold the generator object until the activation has been resumed. 2210 // r4 will hold the generator object until the activation has been resumed.
2158 VisitForStackValue(generator); 2211 VisitForStackValue(generator);
2159 VisitForAccumulatorValue(value); 2212 VisitForAccumulatorValue(value);
2160 __ pop(r4); 2213 __ pop(r4);
2161 2214
2162 // Check generator state.
2163 Label wrong_state, closed_state, done;
2164 __ LoadP(r6, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset));
2165 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
2166 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
2167 __ CmpSmiLiteral(r6, Smi::FromInt(0), r0);
2168 __ beq(&closed_state);
2169 __ blt(&wrong_state);
2170
2171 // Load suspended function and context. 2215 // Load suspended function and context.
2172 __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset)); 2216 __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset));
2173 __ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset)); 2217 __ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
2174 2218
2175 // Load receiver and store as the first argument. 2219 // Load receiver and store as the first argument.
2176 __ LoadP(r5, FieldMemOperand(r4, JSGeneratorObject::kReceiverOffset)); 2220 __ LoadP(r5, FieldMemOperand(r4, JSGeneratorObject::kReceiverOffset));
2177 __ push(r5); 2221 __ push(r5);
2178 2222
2179 // Push holes for the rest of the arguments to the generator function. 2223 // Push holes for the rest of the arguments to the generator function.
2180 __ LoadP(r6, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset)); 2224 __ LoadP(r6, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
2181 __ LoadWordArith( 2225 __ LoadWordArith(
2182 r6, FieldMemOperand(r6, SharedFunctionInfo::kFormalParameterCountOffset)); 2226 r6, FieldMemOperand(r6, SharedFunctionInfo::kFormalParameterCountOffset));
2183 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); 2227 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
2184 Label argument_loop, push_frame; 2228 Label argument_loop, push_frame;
2185 #if V8_TARGET_ARCH_PPC64 2229 #if V8_TARGET_ARCH_PPC64
2186 __ cmpi(r6, Operand::Zero()); 2230 __ cmpi(r6, Operand::Zero());
2187 __ beq(&push_frame); 2231 __ beq(&push_frame);
2188 #else 2232 #else
2189 __ SmiUntag(r6, SetRC); 2233 __ SmiUntag(r6, SetRC);
2190 __ beq(&push_frame, cr0); 2234 __ beq(&push_frame, cr0);
2191 #endif 2235 #endif
2192 __ mtctr(r6); 2236 __ mtctr(r6);
2193 __ bind(&argument_loop); 2237 __ bind(&argument_loop);
2194 __ push(r5); 2238 __ push(r5);
2195 __ bdnz(&argument_loop); 2239 __ bdnz(&argument_loop);
2196 2240
2197 // Enter a new JavaScript frame, and initialize its slots as they were when 2241 // Enter a new JavaScript frame, and initialize its slots as they were when
2198 // the generator was suspended. 2242 // the generator was suspended.
2199 Label resume_frame; 2243 Label resume_frame, done;
2200 __ bind(&push_frame); 2244 __ bind(&push_frame);
2201 __ b(&resume_frame, SetLK); 2245 __ b(&resume_frame, SetLK);
2202 __ b(&done); 2246 __ b(&done);
2203 __ bind(&resume_frame); 2247 __ bind(&resume_frame);
2204 // lr = return address. 2248 // lr = return address.
2205 // fp = caller's frame pointer. 2249 // fp = caller's frame pointer.
2206 // cp = callee's context, 2250 // cp = callee's context,
2207 // r7 = callee's JS function. 2251 // r7 = callee's JS function.
2208 __ PushFixedFrame(r7); 2252 __ PushFixedFrame(r7);
2209 // Adjust FP to point to saved FP. 2253 // Adjust FP to point to saved FP.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 __ bdnz(&operand_loop); 2297 __ bdnz(&operand_loop);
2254 2298
2255 __ bind(&call_resume); 2299 __ bind(&call_resume);
2256 DCHECK(!result_register().is(r4)); 2300 DCHECK(!result_register().is(r4));
2257 __ Push(r4, result_register()); 2301 __ Push(r4, result_register());
2258 __ Push(Smi::FromInt(resume_mode)); 2302 __ Push(Smi::FromInt(resume_mode));
2259 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2303 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2260 // Not reached: the runtime call returns elsewhere. 2304 // Not reached: the runtime call returns elsewhere.
2261 __ stop("not-reached"); 2305 __ stop("not-reached");
2262 2306
2263 // Reach here when generator is closed.
2264 __ bind(&closed_state);
2265 if (resume_mode == JSGeneratorObject::NEXT) {
2266 // Return completed iterator result when generator is closed.
2267 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
2268 __ push(r5);
2269 // Pop value from top-of-stack slot; box result into result register.
2270 EmitCreateIteratorResult(true);
2271 } else {
2272 // Throw the provided value.
2273 __ push(r3);
2274 __ CallRuntime(Runtime::kThrow, 1);
2275 }
2276 __ b(&done);
2277
2278 // Throw error if we attempt to operate on a running generator.
2279 __ bind(&wrong_state);
2280 __ push(r4);
2281 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2282
2283 __ bind(&done); 2307 __ bind(&done);
2284 context()->Plug(result_register()); 2308 context()->Plug(result_register());
2285 } 2309 }
2286 2310
2287 2311
2288 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2312 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2289 Label gc_required; 2313 Label gc_required;
2290 Label allocated; 2314 Label allocated;
2291 2315
2292 const int instance_size = 5 * kPointerSize; 2316 const int instance_size = 5 * kPointerSize;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2370 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2394 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2371 // Stack: receiver, home_object, key. 2395 // Stack: receiver, home_object, key.
2372 SetSourcePosition(prop->position()); 2396 SetSourcePosition(prop->position());
2373 2397
2374 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3); 2398 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
2375 } 2399 }
2376 2400
2377 2401
2378 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2402 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2379 Token::Value op, 2403 Token::Value op,
2380 OverwriteMode mode,
2381 Expression* left_expr, 2404 Expression* left_expr,
2382 Expression* right_expr) { 2405 Expression* right_expr) {
2383 Label done, smi_case, stub_call; 2406 Label done, smi_case, stub_call;
2384 2407
2385 Register scratch1 = r5; 2408 Register scratch1 = r5;
2386 Register scratch2 = r6; 2409 Register scratch2 = r6;
2387 2410
2388 // Get the arguments. 2411 // Get the arguments.
2389 Register left = r4; 2412 Register left = r4;
2390 Register right = r3; 2413 Register right = r3;
2391 __ pop(left); 2414 __ pop(left);
2392 2415
2393 // Perform combined smi check on both operands. 2416 // Perform combined smi check on both operands.
2394 __ orx(scratch1, left, right); 2417 __ orx(scratch1, left, right);
2395 STATIC_ASSERT(kSmiTag == 0); 2418 STATIC_ASSERT(kSmiTag == 0);
2396 JumpPatchSite patch_site(masm_); 2419 JumpPatchSite patch_site(masm_);
2397 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2420 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2398 2421
2399 __ bind(&stub_call); 2422 __ bind(&stub_call);
2400 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); 2423 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2401 CallIC(code, expr->BinaryOperationFeedbackId()); 2424 CallIC(code, expr->BinaryOperationFeedbackId());
2402 patch_site.EmitPatchInfo(); 2425 patch_site.EmitPatchInfo();
2403 __ b(&done); 2426 __ b(&done);
2404 2427
2405 __ bind(&smi_case); 2428 __ bind(&smi_case);
2406 // Smi case. This code works the same way as the smi-smi case in the type 2429 // Smi case. This code works the same way as the smi-smi case in the type
2407 // recording binary operation stub. 2430 // recording binary operation stub.
2408 switch (op) { 2431 switch (op) {
2409 case Token::SAR: 2432 case Token::SAR:
2410 __ GetLeastBitsFromSmi(scratch1, right, 5); 2433 __ GetLeastBitsFromSmi(scratch1, right, 5);
(...skipping 17 matching lines...) Expand all
2428 __ SmiUntag(scratch1, left); 2451 __ SmiUntag(scratch1, left);
2429 __ GetLeastBitsFromSmi(scratch2, right, 5); 2452 __ GetLeastBitsFromSmi(scratch2, right, 5);
2430 __ srw(scratch1, scratch1, scratch2); 2453 __ srw(scratch1, scratch1, scratch2);
2431 // Unsigned shift is not allowed to produce a negative number. 2454 // Unsigned shift is not allowed to produce a negative number.
2432 __ JumpIfNotUnsignedSmiCandidate(scratch1, r0, &stub_call); 2455 __ JumpIfNotUnsignedSmiCandidate(scratch1, r0, &stub_call);
2433 __ SmiTag(right, scratch1); 2456 __ SmiTag(right, scratch1);
2434 break; 2457 break;
2435 } 2458 }
2436 case Token::ADD: { 2459 case Token::ADD: {
2437 __ AddAndCheckForOverflow(scratch1, left, right, scratch2, r0); 2460 __ AddAndCheckForOverflow(scratch1, left, right, scratch2, r0);
2438 __ bne(&stub_call, cr0); 2461 __ BranchOnOverflow(&stub_call);
2439 __ mr(right, scratch1); 2462 __ mr(right, scratch1);
2440 break; 2463 break;
2441 } 2464 }
2442 case Token::SUB: { 2465 case Token::SUB: {
2443 __ SubAndCheckForOverflow(scratch1, left, right, scratch2, r0); 2466 __ SubAndCheckForOverflow(scratch1, left, right, scratch2, r0);
2444 __ bne(&stub_call, cr0); 2467 __ BranchOnOverflow(&stub_call);
2445 __ mr(right, scratch1); 2468 __ mr(right, scratch1);
2446 break; 2469 break;
2447 } 2470 }
2448 case Token::MUL: { 2471 case Token::MUL: {
2449 Label mul_zero; 2472 Label mul_zero;
2450 #if V8_TARGET_ARCH_PPC64 2473 #if V8_TARGET_ARCH_PPC64
2451 // Remove tag from both operands. 2474 // Remove tag from both operands.
2452 __ SmiUntag(ip, right); 2475 __ SmiUntag(ip, right);
2453 __ SmiUntag(r0, left); 2476 __ SmiUntag(r0, left);
2454 __ Mul(scratch1, r0, ip); 2477 __ Mul(scratch1, r0, ip);
2455 // Check for overflowing the smi range - no overflow if higher 33 bits of 2478 // Check for overflowing the smi range - no overflow if higher 33 bits of
2456 // the result are identical. 2479 // the result are identical.
2457 __ TestIfInt32(scratch1, scratch2, ip); 2480 __ TestIfInt32(scratch1, r0);
2458 __ bne(&stub_call); 2481 __ bne(&stub_call);
2459 #else 2482 #else
2460 __ SmiUntag(ip, right); 2483 __ SmiUntag(ip, right);
2461 __ mullw(scratch1, left, ip); 2484 __ mullw(scratch1, left, ip);
2462 __ mulhw(scratch2, left, ip); 2485 __ mulhw(scratch2, left, ip);
2463 // Check for overflowing the smi range - no overflow if higher 33 bits of 2486 // Check for overflowing the smi range - no overflow if higher 33 bits of
2464 // the result are identical. 2487 // the result are identical.
2465 __ TestIfInt32(scratch2, scratch1, ip); 2488 __ TestIfInt32(scratch2, scratch1, ip);
2466 __ bne(&stub_call); 2489 __ bne(&stub_call);
2467 #endif 2490 #endif
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 2531
2509 // No access check is needed here since the constructor is created by the 2532 // No access check is needed here since the constructor is created by the
2510 // class literal. 2533 // class literal.
2511 Register scratch = r4; 2534 Register scratch = r4;
2512 __ LoadP(scratch, 2535 __ LoadP(scratch,
2513 FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset)); 2536 FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
2514 __ push(scratch); 2537 __ push(scratch);
2515 2538
2516 for (int i = 0; i < lit->properties()->length(); i++) { 2539 for (int i = 0; i < lit->properties()->length(); i++) {
2517 ObjectLiteral::Property* property = lit->properties()->at(i); 2540 ObjectLiteral::Property* property = lit->properties()->at(i);
2518 Literal* key = property->key()->AsLiteral();
2519 Expression* value = property->value(); 2541 Expression* value = property->value();
2520 DCHECK(key != NULL);
2521 2542
2522 if (property->is_static()) { 2543 if (property->is_static()) {
2523 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor 2544 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor
2524 } else { 2545 } else {
2525 __ LoadP(scratch, MemOperand(sp, 0)); // prototype 2546 __ LoadP(scratch, MemOperand(sp, 0)); // prototype
2526 } 2547 }
2527 __ push(scratch); 2548 __ push(scratch);
2528 VisitForStackValue(key); 2549 EmitPropertyKey(property, lit->GetIdForProperty(i));
2529 VisitForStackValue(value); 2550 VisitForStackValue(value);
2551 EmitSetHomeObjectIfNeeded(value, 2);
2530 2552
2531 switch (property->kind()) { 2553 switch (property->kind()) {
2532 case ObjectLiteral::Property::CONSTANT: 2554 case ObjectLiteral::Property::CONSTANT:
2533 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2555 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2534 case ObjectLiteral::Property::PROTOTYPE: 2556 case ObjectLiteral::Property::PROTOTYPE:
2535 UNREACHABLE(); 2557 UNREACHABLE();
2536 case ObjectLiteral::Property::COMPUTED: 2558 case ObjectLiteral::Property::COMPUTED:
2537 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2559 __ CallRuntime(Runtime::kDefineClassMethod, 3);
2538 break; 2560 break;
2539 2561
2540 case ObjectLiteral::Property::GETTER: 2562 case ObjectLiteral::Property::GETTER:
2541 __ CallRuntime(Runtime::kDefineClassGetter, 3); 2563 __ mov(r3, Operand(Smi::FromInt(DONT_ENUM)));
2564 __ push(r3);
2565 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4);
2542 break; 2566 break;
2543 2567
2544 case ObjectLiteral::Property::SETTER: 2568 case ObjectLiteral::Property::SETTER:
2545 __ CallRuntime(Runtime::kDefineClassSetter, 3); 2569 __ mov(r3, Operand(Smi::FromInt(DONT_ENUM)));
2570 __ push(r3);
2571 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4);
2546 break; 2572 break;
2547 2573
2548 default: 2574 default:
2549 UNREACHABLE(); 2575 UNREACHABLE();
2550 } 2576 }
2551 } 2577 }
2552 2578
2553 // prototype 2579 // prototype
2554 __ CallRuntime(Runtime::kToFastProperties, 1); 2580 __ CallRuntime(Runtime::kToFastProperties, 1);
2555 2581
2556 // constructor 2582 // constructor
2557 __ CallRuntime(Runtime::kToFastProperties, 1); 2583 __ CallRuntime(Runtime::kToFastProperties, 1);
2558 } 2584 }
2559 2585
2560 2586
2561 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op, 2587 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2562 OverwriteMode mode) {
2563 __ pop(r4); 2588 __ pop(r4);
2564 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); 2589 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2565 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2590 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2566 CallIC(code, expr->BinaryOperationFeedbackId()); 2591 CallIC(code, expr->BinaryOperationFeedbackId());
2567 patch_site.EmitPatchInfo(); 2592 patch_site.EmitPatchInfo();
2568 context()->Plug(r3); 2593 context()->Plug(r3);
2569 } 2594 }
2570 2595
2571 2596
2572 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2597 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2573 DCHECK(expr->IsValidReferenceExpression()); 2598 DCHECK(expr->IsValidReferenceExpression());
2574 2599
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 break; 2654 break;
2630 } 2655 }
2631 case KEYED_PROPERTY: { 2656 case KEYED_PROPERTY: {
2632 __ push(r3); // Preserve value. 2657 __ push(r3); // Preserve value.
2633 VisitForStackValue(prop->obj()); 2658 VisitForStackValue(prop->obj());
2634 VisitForAccumulatorValue(prop->key()); 2659 VisitForAccumulatorValue(prop->key());
2635 __ Move(StoreDescriptor::NameRegister(), r3); 2660 __ Move(StoreDescriptor::NameRegister(), r3);
2636 __ Pop(StoreDescriptor::ValueRegister(), 2661 __ Pop(StoreDescriptor::ValueRegister(),
2637 StoreDescriptor::ReceiverRegister()); 2662 StoreDescriptor::ReceiverRegister());
2638 Handle<Code> ic = 2663 Handle<Code> ic =
2639 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2664 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2640 CallIC(ic); 2665 CallIC(ic);
2641 break; 2666 break;
2642 } 2667 }
2643 } 2668 }
2644 context()->Plug(r3); 2669 context()->Plug(r3);
2645 } 2670 }
2646 2671
2647 2672
2648 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2673 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2649 Variable* var, MemOperand location) { 2674 Variable* var, MemOperand location) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2723 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2699 // Perform the assignment. 2724 // Perform the assignment.
2700 __ bind(&assign); 2725 __ bind(&assign);
2701 EmitStoreToStackLocalOrContextSlot(var, location); 2726 EmitStoreToStackLocalOrContextSlot(var, location);
2702 2727
2703 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { 2728 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2704 if (var->IsLookupSlot()) { 2729 if (var->IsLookupSlot()) {
2705 // Assignment to var. 2730 // Assignment to var.
2706 __ push(r3); // Value. 2731 __ push(r3); // Value.
2707 __ mov(r4, Operand(var->name())); 2732 __ mov(r4, Operand(var->name()));
2708 __ mov(r3, Operand(Smi::FromInt(strict_mode()))); 2733 __ mov(r3, Operand(Smi::FromInt(language_mode())));
2709 __ Push(cp, r4, r3); // Context, name, strict mode. 2734 __ Push(cp, r4, r3); // Context, name, language mode.
2710 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2735 __ CallRuntime(Runtime::kStoreLookupSlot, 4);
2711 } else { 2736 } else {
2712 // Assignment to var or initializing assignment to let/const in harmony 2737 // Assignment to var or initializing assignment to let/const in harmony
2713 // mode. 2738 // mode.
2714 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); 2739 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2715 MemOperand location = VarOperand(var, r4); 2740 MemOperand location = VarOperand(var, r4);
2716 if (generate_debug_code_ && op == Token::INIT_LET) { 2741 if (generate_debug_code_ && op == Token::INIT_LET) {
2717 // Check for an uninitialized let binding. 2742 // Check for an uninitialized let binding.
2718 __ LoadP(r5, location); 2743 __ LoadP(r5, location);
2719 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); 2744 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
2720 __ Check(eq, kLetBindingReInitialization); 2745 __ Check(eq, kLetBindingReInitialization);
2721 } 2746 }
2722 EmitStoreToStackLocalOrContextSlot(var, location); 2747 EmitStoreToStackLocalOrContextSlot(var, location);
2723 } 2748 }
2749 } else if (IsSignallingAssignmentToConst(var, op, language_mode())) {
2750 __ CallRuntime(Runtime::kThrowConstAssignError, 0);
2724 } 2751 }
2725 // Non-initializing assignments to consts are ignored.
2726 } 2752 }
2727 2753
2728 2754
2729 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2755 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2730 // Assignment to a property, using a named store IC. 2756 // Assignment to a property, using a named store IC.
2731 Property* prop = expr->target()->AsProperty(); 2757 Property* prop = expr->target()->AsProperty();
2732 DCHECK(prop != NULL); 2758 DCHECK(prop != NULL);
2733 DCHECK(prop->key()->IsLiteral()); 2759 DCHECK(prop->key()->IsLiteral());
2734 2760
2735 // Record source code position before IC call. 2761 // Record source code position before IC call.
(...skipping 11 matching lines...) Expand all
2747 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2773 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2748 // Assignment to named property of super. 2774 // Assignment to named property of super.
2749 // r3 : value 2775 // r3 : value
2750 // stack : receiver ('this'), home_object 2776 // stack : receiver ('this'), home_object
2751 DCHECK(prop != NULL); 2777 DCHECK(prop != NULL);
2752 Literal* key = prop->key()->AsLiteral(); 2778 Literal* key = prop->key()->AsLiteral();
2753 DCHECK(key != NULL); 2779 DCHECK(key != NULL);
2754 2780
2755 __ Push(key->value()); 2781 __ Push(key->value());
2756 __ Push(r3); 2782 __ Push(r3);
2757 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict 2783 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
2758 : Runtime::kStoreToSuper_Sloppy), 2784 : Runtime::kStoreToSuper_Sloppy),
2759 4); 2785 4);
2760 } 2786 }
2761 2787
2762 2788
2763 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2789 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2764 // Assignment to named property of super. 2790 // Assignment to named property of super.
2765 // r3 : value 2791 // r3 : value
2766 // stack : receiver ('this'), home_object, key 2792 // stack : receiver ('this'), home_object, key
2767 DCHECK(prop != NULL); 2793 DCHECK(prop != NULL);
2768 2794
2769 __ Push(r3); 2795 __ Push(r3);
2770 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict 2796 __ CallRuntime(
2771 : Runtime::kStoreKeyedToSuper_Sloppy), 2797 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
2772 4); 2798 : Runtime::kStoreKeyedToSuper_Sloppy),
2799 4);
2773 } 2800 }
2774 2801
2775 2802
2776 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2803 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2777 // Assignment to a property, using a keyed store IC. 2804 // Assignment to a property, using a keyed store IC.
2778 2805
2779 // Record source code position before IC call. 2806 // Record source code position before IC call.
2780 SetSourcePosition(expr->position()); 2807 SetSourcePosition(expr->position());
2781 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2808 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2782 DCHECK(StoreDescriptor::ValueRegister().is(r3)); 2809 DCHECK(StoreDescriptor::ValueRegister().is(r3));
2783 2810
2784 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2811 Handle<Code> ic =
2812 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2785 CallIC(ic, expr->AssignmentFeedbackId()); 2813 CallIC(ic, expr->AssignmentFeedbackId());
2786 2814
2787 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2815 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2788 context()->Plug(r3); 2816 context()->Plug(r3);
2789 } 2817 }
2790 2818
2791 2819
2792 void FullCodeGenerator::VisitProperty(Property* expr) { 2820 void FullCodeGenerator::VisitProperty(Property* expr) {
2793 Comment cmnt(masm_, "[ Property"); 2821 Comment cmnt(masm_, "[ Property");
2794 Expression* key = expr->key(); 2822 Expression* key = expr->key();
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2966 int arg_count = args->length(); 2994 int arg_count = args->length();
2967 { 2995 {
2968 PreservePositionScope scope(masm()->positions_recorder()); 2996 PreservePositionScope scope(masm()->positions_recorder());
2969 for (int i = 0; i < arg_count; i++) { 2997 for (int i = 0; i < arg_count; i++) {
2970 VisitForStackValue(args->at(i)); 2998 VisitForStackValue(args->at(i));
2971 } 2999 }
2972 } 3000 }
2973 3001
2974 // Record source position of the IC call. 3002 // Record source position of the IC call.
2975 SetSourcePosition(expr->position()); 3003 SetSourcePosition(expr->position());
2976 Handle<Code> ic = CallIC::initialize_stub(isolate(), arg_count, call_type); 3004 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
2977 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); 3005 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
2978 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 3006 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2979 // Don't assign a type feedback id to the IC, since type feedback is provided 3007 // Don't assign a type feedback id to the IC, since type feedback is provided
2980 // by the vector above. 3008 // by the vector above.
2981 CallIC(ic); 3009 CallIC(ic);
2982 3010
2983 RecordJSReturnSite(expr); 3011 RecordJSReturnSite(expr);
2984 // Restore context register. 3012 // Restore context register.
2985 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3013 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2986 context()->DropAndPlug(1, r3); 3014 context()->DropAndPlug(1, r3);
2987 } 3015 }
2988 3016
2989 3017
2990 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 3018 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2991 // r8: copy of the first argument or undefined if it doesn't exist. 3019 // r8: copy of the first argument or undefined if it doesn't exist.
2992 if (arg_count > 0) { 3020 if (arg_count > 0) {
2993 __ LoadP(r8, MemOperand(sp, arg_count * kPointerSize), r0); 3021 __ LoadP(r8, MemOperand(sp, arg_count * kPointerSize), r0);
2994 } else { 3022 } else {
2995 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); 3023 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex);
2996 } 3024 }
2997 3025
2998 // r7: the receiver of the enclosing function. 3026 // r7: the receiver of the enclosing function.
2999 __ LoadP(r7, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3027 __ LoadP(r7, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3000 3028
3001 // r6: the receiver of the enclosing function. 3029 // r6: the receiver of the enclosing function.
3002 int receiver_offset = 2 + info_->scope()->num_parameters(); 3030 int receiver_offset = 2 + info_->scope()->num_parameters();
3003 __ LoadP(r6, MemOperand(fp, receiver_offset * kPointerSize), r0); 3031 __ LoadP(r6, MemOperand(fp, receiver_offset * kPointerSize), r0);
3004 3032
3005 // r5: strict mode. 3033 // r5: language mode.
3006 __ LoadSmiLiteral(r5, Smi::FromInt(strict_mode())); 3034 __ LoadSmiLiteral(r5, Smi::FromInt(language_mode()));
3007 3035
3008 // r4: the start position of the scope the calls resides in. 3036 // r4: the start position of the scope the calls resides in.
3009 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position())); 3037 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position()));
3010 3038
3011 // Do the runtime call. 3039 // Do the runtime call.
3012 __ Push(r8, r7, r6, r5, r4); 3040 __ Push(r8, r7, r6, r5, r4);
3013 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); 3041 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
3014 } 3042 }
3015 3043
3016 3044
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3133 PreservePositionScope scope(masm()->positions_recorder()); 3161 PreservePositionScope scope(masm()->positions_recorder());
3134 VisitForStackValue(property->obj()); 3162 VisitForStackValue(property->obj());
3135 } 3163 }
3136 if (is_named_call) { 3164 if (is_named_call) {
3137 EmitCallWithLoadIC(expr); 3165 EmitCallWithLoadIC(expr);
3138 } else { 3166 } else {
3139 EmitKeyedCallWithLoadIC(expr, property->key()); 3167 EmitKeyedCallWithLoadIC(expr, property->key());
3140 } 3168 }
3141 } 3169 }
3142 } else if (call_type == Call::SUPER_CALL) { 3170 } else if (call_type == Call::SUPER_CALL) {
3143 SuperReference* super_ref = callee->AsSuperReference(); 3171 if (FLAG_experimental_classes) {
3144 EmitLoadSuperConstructor(super_ref); 3172 EmitSuperConstructorCall(expr);
3145 __ Push(result_register()); 3173 } else {
3146 VisitForStackValue(super_ref->this_var()); 3174 SuperReference* super_ref = callee->AsSuperReference();
3147 EmitCall(expr, CallICState::METHOD); 3175 EmitLoadSuperConstructor(super_ref);
3176 __ Push(result_register());
3177 VisitForStackValue(super_ref->this_var());
3178 EmitCall(expr, CallICState::METHOD);
3179 }
3148 } else { 3180 } else {
3149 DCHECK(call_type == Call::OTHER_CALL); 3181 DCHECK(call_type == Call::OTHER_CALL);
3150 // Call to an arbitrary expression not handled specially above. 3182 // Call to an arbitrary expression not handled specially above.
3151 { 3183 {
3152 PreservePositionScope scope(masm()->positions_recorder()); 3184 PreservePositionScope scope(masm()->positions_recorder());
3153 VisitForStackValue(callee); 3185 VisitForStackValue(callee);
3154 } 3186 }
3155 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); 3187 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
3156 __ push(r4); 3188 __ push(r4);
3157 // Emit function call. 3189 // Emit function call.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3206 __ Move(r5, FeedbackVector()); 3238 __ Move(r5, FeedbackVector());
3207 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); 3239 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot()));
3208 3240
3209 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); 3241 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
3210 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 3242 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
3211 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 3243 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
3212 context()->Plug(r3); 3244 context()->Plug(r3);
3213 } 3245 }
3214 3246
3215 3247
3248 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
3249 SuperReference* super_ref = expr->expression()->AsSuperReference();
3250 EmitLoadSuperConstructor(super_ref);
3251 __ push(result_register());
3252
3253 Variable* this_var = super_ref->this_var()->var();
3254
3255 GetVar(r3, this_var);
3256 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
3257 Label uninitialized_this;
3258 __ beq(&uninitialized_this);
3259 __ mov(r3, Operand(this_var->name()));
3260 __ push(r3);
3261 __ CallRuntime(Runtime::kThrowReferenceError, 1);
3262 __ bind(&uninitialized_this);
3263
3264 // Push the arguments ("left-to-right") on the stack.
3265 ZoneList<Expression*>* args = expr->arguments();
3266 int arg_count = args->length();
3267 for (int i = 0; i < arg_count; i++) {
3268 VisitForStackValue(args->at(i));
3269 }
3270
3271 // Call the construct call builtin that handles allocation and
3272 // constructor invocation.
3273 SetSourcePosition(expr->position());
3274
3275 // Load function and argument count into r1 and r0.
3276 __ mov(r3, Operand(arg_count));
3277 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize));
3278
3279 // Record call targets in unoptimized code.
3280 if (FLAG_pretenuring_call_new) {
3281 UNREACHABLE();
3282 /* TODO(dslomov): support pretenuring.
3283 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
3284 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
3285 expr->CallNewFeedbackSlot().ToInt() + 1);
3286 */
3287 }
3288
3289 __ Move(r5, FeedbackVector());
3290 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot()));
3291
3292 // TODO(dslomov): use a different stub and propagate new.target.
3293 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
3294 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
3295
3296 RecordJSReturnSite(expr);
3297
3298 EmitVariableAssignment(this_var, Token::INIT_CONST);
3299 context()->Plug(r3);
3300 }
3301
3302
3216 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 3303 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
3217 ZoneList<Expression*>* args = expr->arguments(); 3304 ZoneList<Expression*>* args = expr->arguments();
3218 DCHECK(args->length() == 1); 3305 DCHECK(args->length() == 1);
3219 3306
3220 VisitForAccumulatorValue(args->at(0)); 3307 VisitForAccumulatorValue(args->at(0));
3221 3308
3222 Label materialize_true, materialize_false; 3309 Label materialize_true, materialize_false;
3223 Label* if_true = NULL; 3310 Label* if_true = NULL;
3224 Label* if_false = NULL; 3311 Label* if_false = NULL;
3225 Label* fall_through = NULL; 3312 Label* fall_through = NULL;
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
4505 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4592 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4506 switch (expr->op()) { 4593 switch (expr->op()) {
4507 case Token::DELETE: { 4594 case Token::DELETE: {
4508 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4595 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4509 Property* property = expr->expression()->AsProperty(); 4596 Property* property = expr->expression()->AsProperty();
4510 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4597 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4511 4598
4512 if (property != NULL) { 4599 if (property != NULL) {
4513 VisitForStackValue(property->obj()); 4600 VisitForStackValue(property->obj());
4514 VisitForStackValue(property->key()); 4601 VisitForStackValue(property->key());
4515 __ LoadSmiLiteral(r4, Smi::FromInt(strict_mode())); 4602 __ LoadSmiLiteral(r4, Smi::FromInt(language_mode()));
4516 __ push(r4); 4603 __ push(r4);
4517 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4604 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4518 context()->Plug(r3); 4605 context()->Plug(r3);
4519 } else if (proxy != NULL) { 4606 } else if (proxy != NULL) {
4520 Variable* var = proxy->var(); 4607 Variable* var = proxy->var();
4521 // Delete of an unqualified identifier is disallowed in strict mode 4608 // Delete of an unqualified identifier is disallowed in strict mode
4522 // but "delete this" is allowed. 4609 // but "delete this" is allowed.
4523 DCHECK(strict_mode() == SLOPPY || var->is_this()); 4610 DCHECK(is_sloppy(language_mode()) || var->is_this());
4524 if (var->IsUnallocated()) { 4611 if (var->IsUnallocated()) {
4525 __ LoadP(r5, GlobalObjectOperand()); 4612 __ LoadP(r5, GlobalObjectOperand());
4526 __ mov(r4, Operand(var->name())); 4613 __ mov(r4, Operand(var->name()));
4527 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); 4614 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY));
4528 __ Push(r5, r4, r3); 4615 __ Push(r5, r4, r3);
4529 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4616 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4530 context()->Plug(r3); 4617 context()->Plug(r3);
4531 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4618 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4532 // Result of deleting non-global, non-dynamic variables is false. 4619 // Result of deleting non-global, non-dynamic variables is false.
4533 // The subexpression does not have side effects. 4620 // The subexpression does not have side effects.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
4761 } 4848 }
4762 } 4849 }
4763 4850
4764 __ bind(&stub_call); 4851 __ bind(&stub_call);
4765 __ mr(r4, r3); 4852 __ mr(r4, r3);
4766 __ LoadSmiLiteral(r3, Smi::FromInt(count_value)); 4853 __ LoadSmiLiteral(r3, Smi::FromInt(count_value));
4767 4854
4768 // Record position before stub call. 4855 // Record position before stub call.
4769 SetSourcePosition(expr->position()); 4856 SetSourcePosition(expr->position());
4770 4857
4771 Handle<Code> code = 4858 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
4772 CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
4773 CallIC(code, expr->CountBinOpFeedbackId()); 4859 CallIC(code, expr->CountBinOpFeedbackId());
4774 patch_site.EmitPatchInfo(); 4860 patch_site.EmitPatchInfo();
4775 __ bind(&done); 4861 __ bind(&done);
4776 4862
4777 // Store the value returned in r3. 4863 // Store the value returned in r3.
4778 switch (assign_type) { 4864 switch (assign_type) {
4779 case VARIABLE: 4865 case VARIABLE:
4780 if (expr->is_postfix()) { 4866 if (expr->is_postfix()) {
4781 { 4867 {
4782 EffectContext context(this); 4868 EffectContext context(this);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4831 } 4917 }
4832 } else { 4918 } else {
4833 context()->Plug(r3); 4919 context()->Plug(r3);
4834 } 4920 }
4835 break; 4921 break;
4836 } 4922 }
4837 case KEYED_PROPERTY: { 4923 case KEYED_PROPERTY: {
4838 __ Pop(StoreDescriptor::ReceiverRegister(), 4924 __ Pop(StoreDescriptor::ReceiverRegister(),
4839 StoreDescriptor::NameRegister()); 4925 StoreDescriptor::NameRegister());
4840 Handle<Code> ic = 4926 Handle<Code> ic =
4841 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 4927 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
4842 CallIC(ic, expr->CountStoreFeedbackId()); 4928 CallIC(ic, expr->CountStoreFeedbackId());
4843 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4929 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4844 if (expr->is_postfix()) { 4930 if (expr->is_postfix()) {
4845 if (!context()->IsEffect()) { 4931 if (!context()->IsEffect()) {
4846 context()->PlugTOS(); 4932 context()->PlugTOS();
4847 } 4933 }
4848 } else { 4934 } else {
4849 context()->Plug(r3); 4935 context()->Plug(r3);
4850 } 4936 }
4851 break; 4937 break;
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
5285 return ON_STACK_REPLACEMENT; 5371 return ON_STACK_REPLACEMENT;
5286 } 5372 }
5287 5373
5288 DCHECK(interrupt_address == 5374 DCHECK(interrupt_address ==
5289 isolate->builtins()->OsrAfterStackCheck()->entry()); 5375 isolate->builtins()->OsrAfterStackCheck()->entry());
5290 return OSR_AFTER_STACK_CHECK; 5376 return OSR_AFTER_STACK_CHECK;
5291 } 5377 }
5292 } 5378 }
5293 } // namespace v8::internal 5379 } // namespace v8::internal
5294 #endif // V8_TARGET_ARCH_PPC 5380 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ppc/disasm-ppc.cc ('k') | src/ppc/interface-descriptors-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698