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

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
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/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 GenerateDeferredCode() && 96 GenerateDeferredCode() &&
97 GenerateJumpTable() && 97 GenerateJumpTable() &&
98 GenerateSafepointTable(); 98 GenerateSafepointTable();
99 } 99 }
100 100
101 101
102 void LCodeGen::FinishCode(Handle<Code> code) { 102 void LCodeGen::FinishCode(Handle<Code> code) {
103 ASSERT(is_done()); 103 ASSERT(is_done());
104 code->set_stack_slots(GetStackSlotCount()); 104 code->set_stack_slots(GetStackSlotCount());
105 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 105 code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
106 RegisterDependentCodeForEmbeddedMaps(code); 106 if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
107 PopulateDeoptimizationData(code); 107 PopulateDeoptimizationData(code);
108 if (!info()->IsStub()) { 108 if (!info()->IsStub()) {
109 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); 109 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
110 } 110 }
111 info()->CommitDependencies(code); 111 info()->CommitDependencies(code);
112 } 112 }
113 113
114 114
115 void LCodeGen::Abort(BailoutReason reason) { 115 void LCodeGen::Abort(BailoutReason reason) {
116 info()->set_bailout_reason(reason); 116 info()->set_bailout_reason(reason);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { 285 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) {
286 SaveCallerDoubles(); 286 SaveCallerDoubles();
287 } 287 }
288 } 288 }
289 289
290 // Possibly allocate a local context. 290 // Possibly allocate a local context.
291 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 291 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
292 if (heap_slots > 0) { 292 if (heap_slots > 0) {
293 Comment(";;; Allocate local context"); 293 Comment(";;; Allocate local context");
294 // Argument to NewContext is the function, which is still in edi. 294 // Argument to NewContext is the function, which is still in edi.
295 __ push(edi);
296 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 295 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
297 FastNewContextStub stub(heap_slots); 296 FastNewContextStub stub(heap_slots);
298 __ CallStub(&stub); 297 __ CallStub(&stub);
299 } else { 298 } else {
299 __ push(edi);
300 __ CallRuntime(Runtime::kNewFunctionContext, 1); 300 __ CallRuntime(Runtime::kNewFunctionContext, 1);
301 } 301 }
302 RecordSafepoint(Safepoint::kNoLazyDeopt); 302 RecordSafepoint(Safepoint::kNoLazyDeopt);
303 // Context is returned in both eax and esi. It replaces the context 303 // Context is returned in eax. It replaces the context passed to us.
304 // passed to us. It's saved in the stack and kept live in esi. 304 // It's saved in the stack and kept live in esi.
305 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 305 __ mov(esi, eax);
306 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax);
306 307
307 // Copy parameters into context if necessary. 308 // Copy parameters into context if necessary.
308 int num_parameters = scope()->num_parameters(); 309 int num_parameters = scope()->num_parameters();
309 for (int i = 0; i < num_parameters; i++) { 310 for (int i = 0; i < num_parameters; i++) {
310 Variable* var = scope()->parameter(i); 311 Variable* var = scope()->parameter(i);
311 if (var->IsContextSlot()) { 312 if (var->IsContextSlot()) {
312 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 313 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
313 (num_parameters - 1 - i) * kPointerSize; 314 (num_parameters - 1 - i) * kPointerSize;
314 // Load parameter from stack. 315 // Load parameter from stack.
315 __ mov(eax, Operand(ebp, parameter_offset)); 316 __ mov(eax, Operand(ebp, parameter_offset));
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 bool LCodeGen::GenerateDeferredCode() { 469 bool LCodeGen::GenerateDeferredCode() {
469 ASSERT(is_generating()); 470 ASSERT(is_generating());
470 if (deferred_.length() > 0) { 471 if (deferred_.length() > 0) {
471 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 472 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
472 LDeferredCode* code = deferred_[i]; 473 LDeferredCode* code = deferred_[i];
473 X87Stack copy(code->x87_stack()); 474 X87Stack copy(code->x87_stack());
474 x87_stack_ = copy; 475 x87_stack_ = copy;
475 476
476 HValue* value = 477 HValue* value =
477 instructions_->at(code->instruction_index())->hydrogen_value(); 478 instructions_->at(code->instruction_index())->hydrogen_value();
478 RecordAndWritePosition(value->position()); 479 RecordAndWritePosition(
480 chunk()->graph()->SourcePositionToScriptPosition(value->position()));
479 481
480 Comment(";;; <@%d,#%d> " 482 Comment(";;; <@%d,#%d> "
481 "-------------------- Deferred %s --------------------", 483 "-------------------- Deferred %s --------------------",
482 code->instruction_index(), 484 code->instruction_index(),
483 code->instr()->hydrogen_value()->id(), 485 code->instr()->hydrogen_value()->id(),
484 code->instr()->Mnemonic()); 486 code->instr()->Mnemonic());
485 __ bind(code->entry()); 487 __ bind(code->entry());
486 if (NeedsDeferredFrame()) { 488 if (NeedsDeferredFrame()) {
487 Comment(";;; Build frame"); 489 Comment(";;; Build frame");
488 ASSERT(!frame_is_built_); 490 ASSERT(!frame_is_built_);
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 1172 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
1171 int length = deoptimizations_.length(); 1173 int length = deoptimizations_.length();
1172 if (length == 0) return; 1174 if (length == 0) return;
1173 Handle<DeoptimizationInputData> data = 1175 Handle<DeoptimizationInputData> data =
1174 factory()->NewDeoptimizationInputData(length, TENURED); 1176 factory()->NewDeoptimizationInputData(length, TENURED);
1175 1177
1176 Handle<ByteArray> translations = 1178 Handle<ByteArray> translations =
1177 translations_.CreateByteArray(isolate()->factory()); 1179 translations_.CreateByteArray(isolate()->factory());
1178 data->SetTranslationByteArray(*translations); 1180 data->SetTranslationByteArray(*translations);
1179 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 1181 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
1182 data->SetOptimizationId(Smi::FromInt(info_->optimization_id()));
1183 if (info_->IsOptimizing()) {
1184 // Reference to shared function info does not change between phases.
1185 AllowDeferredHandleDereference allow_handle_dereference;
1186 data->SetSharedFunctionInfo(*info_->shared_info());
1187 } else {
1188 data->SetSharedFunctionInfo(Smi::FromInt(0));
1189 }
1180 1190
1181 Handle<FixedArray> literals = 1191 Handle<FixedArray> literals =
1182 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 1192 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
1183 { AllowDeferredHandleDereference copy_handles; 1193 { AllowDeferredHandleDereference copy_handles;
1184 for (int i = 0; i < deoptimization_literals_.length(); i++) { 1194 for (int i = 0; i < deoptimization_literals_.length(); i++) {
1185 literals->set(i, *deoptimization_literals_[i]); 1195 literals->set(i, *deoptimization_literals_[i]);
1186 } 1196 }
1187 data->SetLiteralArray(*literals); 1197 data->SetLiteralArray(*literals);
1188 } 1198 }
1189 1199
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 1339
1330 void LCodeGen::DoParameter(LParameter* instr) { 1340 void LCodeGen::DoParameter(LParameter* instr) {
1331 // Nothing to do. 1341 // Nothing to do.
1332 } 1342 }
1333 1343
1334 1344
1335 void LCodeGen::DoCallStub(LCallStub* instr) { 1345 void LCodeGen::DoCallStub(LCallStub* instr) {
1336 ASSERT(ToRegister(instr->context()).is(esi)); 1346 ASSERT(ToRegister(instr->context()).is(esi));
1337 ASSERT(ToRegister(instr->result()).is(eax)); 1347 ASSERT(ToRegister(instr->result()).is(eax));
1338 switch (instr->hydrogen()->major_key()) { 1348 switch (instr->hydrogen()->major_key()) {
1339 case CodeStub::RegExpConstructResult: {
1340 RegExpConstructResultStub stub;
1341 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1342 break;
1343 }
1344 case CodeStub::RegExpExec: { 1349 case CodeStub::RegExpExec: {
1345 RegExpExecStub stub; 1350 RegExpExecStub stub;
1346 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1351 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1347 break; 1352 break;
1348 } 1353 }
1349 case CodeStub::SubString: { 1354 case CodeStub::SubString: {
1350 SubStringStub stub; 1355 SubStringStub stub;
1351 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1356 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1352 break; 1357 break;
1353 } 1358 }
(...skipping 10 matching lines...) Expand all
1364 1369
1365 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1370 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1366 GenerateOsrPrologue(); 1371 GenerateOsrPrologue();
1367 } 1372 }
1368 1373
1369 1374
1370 void LCodeGen::DoModI(LModI* instr) { 1375 void LCodeGen::DoModI(LModI* instr) {
1371 HMod* hmod = instr->hydrogen(); 1376 HMod* hmod = instr->hydrogen();
1372 HValue* left = hmod->left(); 1377 HValue* left = hmod->left();
1373 HValue* right = hmod->right(); 1378 HValue* right = hmod->right();
1374 if (hmod->HasPowerOf2Divisor()) { 1379 if (hmod->RightIsPowerOf2()) {
1375 // TODO(svenpanne) We should really do the strength reduction on the 1380 // TODO(svenpanne) We should really do the strength reduction on the
1376 // Hydrogen level. 1381 // Hydrogen level.
1377 Register left_reg = ToRegister(instr->left()); 1382 Register left_reg = ToRegister(instr->left());
1378 ASSERT(left_reg.is(ToRegister(instr->result()))); 1383 ASSERT(left_reg.is(ToRegister(instr->result())));
1379 1384
1380 // Note: The code below even works when right contains kMinInt. 1385 // Note: The code below even works when right contains kMinInt.
1381 int32_t divisor = Abs(right->GetInteger32Constant()); 1386 int32_t divisor = Abs(right->GetInteger32Constant());
1382 1387
1383 Label left_is_not_negative, done; 1388 Label left_is_not_negative, done;
1384 if (left->CanBeNegative()) { 1389 if (left->CanBeNegative()) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 __ jmp(&done, Label::kNear); 1451 __ jmp(&done, Label::kNear);
1447 __ bind(&positive_left); 1452 __ bind(&positive_left);
1448 } 1453 }
1449 __ idiv(right_reg); 1454 __ idiv(right_reg);
1450 __ bind(&done); 1455 __ bind(&done);
1451 } 1456 }
1452 } 1457 }
1453 1458
1454 1459
1455 void LCodeGen::DoDivI(LDivI* instr) { 1460 void LCodeGen::DoDivI(LDivI* instr) {
1456 if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) { 1461 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
1457 Register dividend = ToRegister(instr->left()); 1462 Register dividend = ToRegister(instr->left());
1458 int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); 1463 HDiv* hdiv = instr->hydrogen();
1459 int32_t test_value = 0; 1464 int32_t divisor = hdiv->right()->GetInteger32Constant();
1460 int32_t power = 0; 1465 Register result = ToRegister(instr->result());
1466 ASSERT(!result.is(dividend));
1461 1467
1462 if (divisor > 0) { 1468 // Check for (0 / -x) that will produce negative zero.
1463 test_value = divisor - 1; 1469 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 &&
1464 power = WhichPowerOf2(divisor); 1470 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1465 } else { 1471 __ test(dividend, Operand(dividend));
1466 // Check for (0 / -x) that will produce negative zero. 1472 DeoptimizeIf(zero, instr->environment());
1467 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1468 __ test(dividend, Operand(dividend));
1469 DeoptimizeIf(zero, instr->environment());
1470 }
1471 // Check for (kMinInt / -1).
1472 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1473 __ cmp(dividend, kMinInt);
1474 DeoptimizeIf(zero, instr->environment());
1475 }
1476 test_value = - divisor - 1;
1477 power = WhichPowerOf2(-divisor);
1478 } 1473 }
1479 1474 // Check for (kMinInt / -1).
1480 if (test_value != 0) { 1475 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1481 if (instr->hydrogen()->CheckFlag( 1476 hdiv->CheckFlag(HValue::kCanOverflow)) {
1482 HInstruction::kAllUsesTruncatingToInt32)) { 1477 __ cmp(dividend, kMinInt);
1483 Label done, negative; 1478 DeoptimizeIf(zero, instr->environment());
1484 __ cmp(dividend, 0); 1479 }
1485 __ j(less, &negative, Label::kNear); 1480 // Deoptimize if remainder will not be 0.
1486 __ sar(dividend, power); 1481 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1487 if (divisor < 0) __ neg(dividend); 1482 Abs(divisor) != 1) {
1488 __ jmp(&done, Label::kNear); 1483 __ test(dividend, Immediate(Abs(divisor) - 1));
1489
1490 __ bind(&negative);
1491 __ neg(dividend);
1492 __ sar(dividend, power);
1493 if (divisor > 0) __ neg(dividend);
1494 __ bind(&done);
1495 return; // Don't fall through to "__ neg" below.
1496 } else {
1497 // Deoptimize if remainder is not 0.
1498 __ test(dividend, Immediate(test_value));
1499 DeoptimizeIf(not_zero, instr->environment()); 1484 DeoptimizeIf(not_zero, instr->environment());
1500 __ sar(dividend, power);
1501 }
1502 } 1485 }
1503 1486 __ Move(result, dividend);
1504 if (divisor < 0) __ neg(dividend); 1487 int32_t shift = WhichPowerOf2(Abs(divisor));
1505 1488 if (shift > 0) {
1489 // The arithmetic shift is always OK, the 'if' is an optimization only.
1490 if (shift > 1) __ sar(result, 31);
1491 __ shr(result, 32 - shift);
1492 __ add(result, dividend);
1493 __ sar(result, shift);
1494 }
1495 if (divisor < 0) __ neg(result);
1506 return; 1496 return;
1507 } 1497 }
1508 1498
1509 LOperand* right = instr->right(); 1499 LOperand* right = instr->right();
1510 ASSERT(ToRegister(instr->result()).is(eax)); 1500 ASSERT(ToRegister(instr->result()).is(eax));
1511 ASSERT(ToRegister(instr->left()).is(eax)); 1501 ASSERT(ToRegister(instr->left()).is(eax));
1512 ASSERT(!ToRegister(instr->right()).is(eax)); 1502 ASSERT(!ToRegister(instr->right()).is(eax));
1513 ASSERT(!ToRegister(instr->right()).is(edx)); 1503 ASSERT(!ToRegister(instr->right()).is(edx));
1514 1504
1515 Register left_reg = eax; 1505 Register left_reg = eax;
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 } 1955 }
1966 1956
1967 1957
1968 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1958 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1969 Register result = ToRegister(instr->result()); 1959 Register result = ToRegister(instr->result());
1970 Register map = ToRegister(instr->value()); 1960 Register map = ToRegister(instr->value());
1971 __ EnumLength(result, map); 1961 __ EnumLength(result, map);
1972 } 1962 }
1973 1963
1974 1964
1975 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1976 Register result = ToRegister(instr->result());
1977 Register input = ToRegister(instr->value());
1978
1979 // Load map into |result|.
1980 __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
1981 // Load the map's "bit field 2" into |result|. We only need the first byte,
1982 // but the following masking takes care of that anyway.
1983 __ mov(result, FieldOperand(result, Map::kBitField2Offset));
1984 // Retrieve elements_kind from bit field 2.
1985 __ and_(result, Map::kElementsKindMask);
1986 __ shr(result, Map::kElementsKindShift);
1987 }
1988
1989
1990 void LCodeGen::DoValueOf(LValueOf* instr) {
1991 Register input = ToRegister(instr->value());
1992 Register result = ToRegister(instr->result());
1993 Register map = ToRegister(instr->temp());
1994 ASSERT(input.is(result));
1995
1996 Label done;
1997
1998 if (!instr->hydrogen()->value()->IsHeapObject()) {
1999 // If the object is a smi return the object.
2000 __ JumpIfSmi(input, &done, Label::kNear);
2001 }
2002
2003 // If the object is not a value type, return the object.
2004 __ CmpObjectType(input, JS_VALUE_TYPE, map);
2005 __ j(not_equal, &done, Label::kNear);
2006 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
2007
2008 __ bind(&done);
2009 }
2010
2011
2012 void LCodeGen::DoDateField(LDateField* instr) { 1965 void LCodeGen::DoDateField(LDateField* instr) {
2013 Register object = ToRegister(instr->date()); 1966 Register object = ToRegister(instr->date());
2014 Register result = ToRegister(instr->result()); 1967 Register result = ToRegister(instr->result());
2015 Register scratch = ToRegister(instr->temp()); 1968 Register scratch = ToRegister(instr->temp());
2016 Smi* index = instr->index(); 1969 Smi* index = instr->index();
2017 Label runtime, done; 1970 Label runtime, done;
2018 ASSERT(object.is(result)); 1971 ASSERT(object.is(result));
2019 ASSERT(object.is(eax)); 1972 ASSERT(object.is(eax));
2020 1973
2021 __ test(object, Immediate(kSmiTagMask)); 1974 __ test(object, Immediate(kSmiTagMask));
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 Register value = ToRegister(instr->value()); 2076 Register value = ToRegister(instr->value());
2124 if (encoding == String::ONE_BYTE_ENCODING) { 2077 if (encoding == String::ONE_BYTE_ENCODING) {
2125 __ mov_b(operand, value); 2078 __ mov_b(operand, value);
2126 } else { 2079 } else {
2127 __ mov_w(operand, value); 2080 __ mov_w(operand, value);
2128 } 2081 }
2129 } 2082 }
2130 } 2083 }
2131 2084
2132 2085
2133 void LCodeGen::DoThrow(LThrow* instr) {
2134 __ push(ToOperand(instr->value()));
2135 ASSERT(ToRegister(instr->context()).is(esi));
2136 CallRuntime(Runtime::kThrow, 1, instr);
2137
2138 if (FLAG_debug_code) {
2139 Comment("Unreachable code.");
2140 __ int3();
2141 }
2142 }
2143
2144
2145 void LCodeGen::DoAddI(LAddI* instr) { 2086 void LCodeGen::DoAddI(LAddI* instr) {
2146 LOperand* left = instr->left(); 2087 LOperand* left = instr->left();
2147 LOperand* right = instr->right(); 2088 LOperand* right = instr->right();
2148 2089
2149 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 2090 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
2150 if (right->IsConstantOperand()) { 2091 if (right->IsConstantOperand()) {
2151 int32_t offset = ToRepresentation(LConstantOperand::cast(right), 2092 int32_t offset = ToRepresentation(LConstantOperand::cast(right),
2152 instr->hydrogen()->representation()); 2093 instr->hydrogen()->representation());
2153 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); 2094 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
2154 } else { 2095 } else {
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3259 Register result = ToRegister(instr->result()); 3200 Register result = ToRegister(instr->result());
3260 MemOperand operand = instr->object()->IsConstantOperand() 3201 MemOperand operand = instr->object()->IsConstantOperand()
3261 ? MemOperand::StaticVariable(ToExternalReference( 3202 ? MemOperand::StaticVariable(ToExternalReference(
3262 LConstantOperand::cast(instr->object()))) 3203 LConstantOperand::cast(instr->object())))
3263 : MemOperand(ToRegister(instr->object()), offset); 3204 : MemOperand(ToRegister(instr->object()), offset);
3264 __ Load(result, operand, access.representation()); 3205 __ Load(result, operand, access.representation());
3265 return; 3206 return;
3266 } 3207 }
3267 3208
3268 Register object = ToRegister(instr->object()); 3209 Register object = ToRegister(instr->object());
3269 if (FLAG_track_double_fields && 3210 if (instr->hydrogen()->representation().IsDouble()) {
3270 instr->hydrogen()->representation().IsDouble()) {
3271 if (CpuFeatures::IsSupported(SSE2)) { 3211 if (CpuFeatures::IsSupported(SSE2)) {
3272 CpuFeatureScope scope(masm(), SSE2); 3212 CpuFeatureScope scope(masm(), SSE2);
3273 XMMRegister result = ToDoubleRegister(instr->result()); 3213 XMMRegister result = ToDoubleRegister(instr->result());
3274 __ movsd(result, FieldOperand(object, offset)); 3214 __ movsd(result, FieldOperand(object, offset));
3275 } else { 3215 } else {
3276 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); 3216 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset));
3277 } 3217 }
3278 return; 3218 return;
3279 } 3219 }
3280 3220
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3357 __ bind(&done); 3297 __ bind(&done);
3358 } 3298 }
3359 3299
3360 3300
3361 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { 3301 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3362 Register result = ToRegister(instr->result()); 3302 Register result = ToRegister(instr->result());
3363 __ LoadRoot(result, instr->index()); 3303 __ LoadRoot(result, instr->index());
3364 } 3304 }
3365 3305
3366 3306
3367 void LCodeGen::DoLoadExternalArrayPointer(
3368 LLoadExternalArrayPointer* instr) {
3369 Register result = ToRegister(instr->result());
3370 Register input = ToRegister(instr->object());
3371 __ mov(result, FieldOperand(input,
3372 ExternalArray::kExternalPointerOffset));
3373 }
3374
3375
3376 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3307 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3377 Register arguments = ToRegister(instr->arguments()); 3308 Register arguments = ToRegister(instr->arguments());
3378 Register result = ToRegister(instr->result()); 3309 Register result = ToRegister(instr->result());
3379 if (instr->length()->IsConstantOperand() && 3310 if (instr->length()->IsConstantOperand() &&
3380 instr->index()->IsConstantOperand()) { 3311 instr->index()->IsConstantOperand()) {
3381 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3312 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3382 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 3313 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3383 int index = (const_length - const_index) + 1; 3314 int index = (const_length - const_index) + 1;
3384 __ mov(result, Operand(arguments, index * kPointerSize)); 3315 __ mov(result, Operand(arguments, index * kPointerSize));
3385 } else { 3316 } else {
(...skipping 15 matching lines...) Expand all
3401 elements_kind)) { 3332 elements_kind)) {
3402 __ SmiUntag(ToRegister(key)); 3333 __ SmiUntag(ToRegister(key));
3403 } 3334 }
3404 Operand operand(BuildFastArrayOperand( 3335 Operand operand(BuildFastArrayOperand(
3405 instr->elements(), 3336 instr->elements(),
3406 key, 3337 key,
3407 instr->hydrogen()->key()->representation(), 3338 instr->hydrogen()->key()->representation(),
3408 elements_kind, 3339 elements_kind,
3409 0, 3340 0,
3410 instr->additional_index())); 3341 instr->additional_index()));
3411 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3342 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3412 elements_kind == FLOAT32_ELEMENTS) { 3343 elements_kind == FLOAT32_ELEMENTS) {
3413 if (CpuFeatures::IsSupported(SSE2)) { 3344 if (CpuFeatures::IsSupported(SSE2)) {
3414 CpuFeatureScope scope(masm(), SSE2); 3345 CpuFeatureScope scope(masm(), SSE2);
3415 XMMRegister result(ToDoubleRegister(instr->result())); 3346 XMMRegister result(ToDoubleRegister(instr->result()));
3416 __ movss(result, operand); 3347 __ movss(result, operand);
3417 __ cvtss2sd(result, result); 3348 __ cvtss2sd(result, result);
3418 } else { 3349 } else {
3419 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); 3350 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand);
3420 } 3351 }
3421 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 3352 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
3422 elements_kind == FLOAT64_ELEMENTS) { 3353 elements_kind == FLOAT64_ELEMENTS) {
3423 if (CpuFeatures::IsSupported(SSE2)) { 3354 if (CpuFeatures::IsSupported(SSE2)) {
3424 CpuFeatureScope scope(masm(), SSE2); 3355 CpuFeatureScope scope(masm(), SSE2);
3425 __ movsd(ToDoubleRegister(instr->result()), operand); 3356 __ movsd(ToDoubleRegister(instr->result()), operand);
3426 } else { 3357 } else {
3427 X87Mov(ToX87Register(instr->result()), operand); 3358 X87Mov(ToX87Register(instr->result()), operand);
3428 } 3359 }
3429 } else { 3360 } else {
3430 Register result(ToRegister(instr->result())); 3361 Register result(ToRegister(instr->result()));
3431 switch (elements_kind) { 3362 switch (elements_kind) {
3432 case EXTERNAL_BYTE_ELEMENTS: 3363 case EXTERNAL_INT8_ELEMENTS:
3433 case INT8_ELEMENTS: 3364 case INT8_ELEMENTS:
3434 __ movsx_b(result, operand); 3365 __ movsx_b(result, operand);
3435 break; 3366 break;
3436 case EXTERNAL_PIXEL_ELEMENTS: 3367 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
3437 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3368 case EXTERNAL_UINT8_ELEMENTS:
3438 case UINT8_ELEMENTS: 3369 case UINT8_ELEMENTS:
3439 case UINT8_CLAMPED_ELEMENTS: 3370 case UINT8_CLAMPED_ELEMENTS:
3440 __ movzx_b(result, operand); 3371 __ movzx_b(result, operand);
3441 break; 3372 break;
3442 case EXTERNAL_SHORT_ELEMENTS: 3373 case EXTERNAL_INT16_ELEMENTS:
3443 case INT16_ELEMENTS: 3374 case INT16_ELEMENTS:
3444 __ movsx_w(result, operand); 3375 __ movsx_w(result, operand);
3445 break; 3376 break;
3446 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3377 case EXTERNAL_UINT16_ELEMENTS:
3447 case UINT16_ELEMENTS: 3378 case UINT16_ELEMENTS:
3448 __ movzx_w(result, operand); 3379 __ movzx_w(result, operand);
3449 break; 3380 break;
3450 case EXTERNAL_INT_ELEMENTS: 3381 case EXTERNAL_INT32_ELEMENTS:
3451 case INT32_ELEMENTS: 3382 case INT32_ELEMENTS:
3452 __ mov(result, operand); 3383 __ mov(result, operand);
3453 break; 3384 break;
3454 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3385 case EXTERNAL_UINT32_ELEMENTS:
3455 case UINT32_ELEMENTS: 3386 case UINT32_ELEMENTS:
3456 __ mov(result, operand); 3387 __ mov(result, operand);
3457 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3388 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3458 __ test(result, Operand(result)); 3389 __ test(result, Operand(result));
3459 DeoptimizeIf(negative, instr->environment()); 3390 DeoptimizeIf(negative, instr->environment());
3460 } 3391 }
3461 break; 3392 break;
3462 case EXTERNAL_FLOAT_ELEMENTS: 3393 case EXTERNAL_FLOAT32_ELEMENTS:
3463 case EXTERNAL_DOUBLE_ELEMENTS: 3394 case EXTERNAL_FLOAT64_ELEMENTS:
3464 case FLOAT32_ELEMENTS: 3395 case FLOAT32_ELEMENTS:
3465 case FLOAT64_ELEMENTS: 3396 case FLOAT64_ELEMENTS:
3466 case FAST_SMI_ELEMENTS: 3397 case FAST_SMI_ELEMENTS:
3467 case FAST_ELEMENTS: 3398 case FAST_ELEMENTS:
3468 case FAST_DOUBLE_ELEMENTS: 3399 case FAST_DOUBLE_ELEMENTS:
3469 case FAST_HOLEY_SMI_ELEMENTS: 3400 case FAST_HOLEY_SMI_ELEMENTS:
3470 case FAST_HOLEY_ELEMENTS: 3401 case FAST_HOLEY_ELEMENTS:
3471 case FAST_HOLEY_DOUBLE_ELEMENTS: 3402 case FAST_HOLEY_DOUBLE_ELEMENTS:
3472 case DICTIONARY_ELEMENTS: 3403 case DICTIONARY_ELEMENTS:
3473 case NON_STRICT_ARGUMENTS_ELEMENTS: 3404 case NON_STRICT_ARGUMENTS_ELEMENTS:
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 __ SmiUntag(result); 3568 __ SmiUntag(result);
3638 3569
3639 // Argument length is in result register. 3570 // Argument length is in result register.
3640 __ bind(&done); 3571 __ bind(&done);
3641 } 3572 }
3642 3573
3643 3574
3644 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3575 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3645 Register receiver = ToRegister(instr->receiver()); 3576 Register receiver = ToRegister(instr->receiver());
3646 Register function = ToRegister(instr->function()); 3577 Register function = ToRegister(instr->function());
3647 Register scratch = ToRegister(instr->temp());
3648 3578
3649 // If the receiver is null or undefined, we have to pass the global 3579 // If the receiver is null or undefined, we have to pass the global
3650 // object as a receiver to normal functions. Values have to be 3580 // object as a receiver to normal functions. Values have to be
3651 // passed unchanged to builtins and strict-mode functions. 3581 // passed unchanged to builtins and strict-mode functions.
3652 Label receiver_ok, global_object; 3582 Label receiver_ok, global_object;
3653 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3583 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
3584 Register scratch = ToRegister(instr->temp());
3654 3585
3655 // Do not transform the receiver to object for strict mode 3586 if (!instr->hydrogen()->known_function()) {
3656 // functions. 3587 // Do not transform the receiver to object for strict mode
3657 __ mov(scratch, 3588 // functions.
3658 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3589 __ mov(scratch,
3659 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset), 3590 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3660 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 3591 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
3661 __ j(not_equal, &receiver_ok, dist); 3592 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
3593 __ j(not_equal, &receiver_ok, dist);
3662 3594
3663 // Do not transform the receiver to object for builtins. 3595 // Do not transform the receiver to object for builtins.
3664 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset), 3596 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
3665 1 << SharedFunctionInfo::kNativeBitWithinByte); 3597 1 << SharedFunctionInfo::kNativeBitWithinByte);
3666 __ j(not_equal, &receiver_ok, dist); 3598 __ j(not_equal, &receiver_ok, dist);
3599 }
3667 3600
3668 // Normal function. Replace undefined or null with global receiver. 3601 // Normal function. Replace undefined or null with global receiver.
3669 __ cmp(receiver, factory()->null_value()); 3602 __ cmp(receiver, factory()->null_value());
3670 __ j(equal, &global_object, Label::kNear); 3603 __ j(equal, &global_object, Label::kNear);
3671 __ cmp(receiver, factory()->undefined_value()); 3604 __ cmp(receiver, factory()->undefined_value());
3672 __ j(equal, &global_object, Label::kNear); 3605 __ j(equal, &global_object, Label::kNear);
3673 3606
3674 // The receiver should be a JS object. 3607 // The receiver should be a JS object.
3675 __ test(receiver, Immediate(kSmiTagMask)); 3608 __ test(receiver, Immediate(kSmiTagMask));
3676 DeoptimizeIf(equal, instr->environment()); 3609 DeoptimizeIf(equal, instr->environment());
3677 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); 3610 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
3678 DeoptimizeIf(below, instr->environment()); 3611 DeoptimizeIf(below, instr->environment());
3612
3679 __ jmp(&receiver_ok, Label::kNear); 3613 __ jmp(&receiver_ok, Label::kNear);
3680
3681 __ bind(&global_object); 3614 __ bind(&global_object);
3682 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset)); 3615 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset));
3683 __ mov(receiver, 3616 const int global_offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
3684 Operand(receiver, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 3617 __ mov(receiver, Operand(receiver, global_offset));
3685 __ mov(receiver, FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 3618 const int receiver_offset = GlobalObject::kGlobalReceiverOffset;
3686 3619 __ mov(receiver, FieldOperand(receiver, receiver_offset));
3687 __ bind(&receiver_ok); 3620 __ bind(&receiver_ok);
3688 } 3621 }
3689 3622
3690 3623
3691 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3624 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3692 Register receiver = ToRegister(instr->receiver()); 3625 Register receiver = ToRegister(instr->receiver());
3693 Register function = ToRegister(instr->function()); 3626 Register function = ToRegister(instr->function());
3694 Register length = ToRegister(instr->length()); 3627 Register length = ToRegister(instr->length());
3695 Register elements = ToRegister(instr->elements()); 3628 Register elements = ToRegister(instr->elements());
3696 ASSERT(receiver.is(eax)); // Used for parameter count. 3629 ASSERT(receiver.is(eax)); // Used for parameter count.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 Register result = ToRegister(instr->result()); 3687 Register result = ToRegister(instr->result());
3755 if (info()->IsOptimizing()) { 3688 if (info()->IsOptimizing()) {
3756 __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset)); 3689 __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset));
3757 } else { 3690 } else {
3758 // If there is no frame, the context must be in esi. 3691 // If there is no frame, the context must be in esi.
3759 ASSERT(result.is(esi)); 3692 ASSERT(result.is(esi));
3760 } 3693 }
3761 } 3694 }
3762 3695
3763 3696
3764 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3765 Register context = ToRegister(instr->context());
3766 Register result = ToRegister(instr->result());
3767 __ mov(result,
3768 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3769 }
3770
3771
3772 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3697 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3773 ASSERT(ToRegister(instr->context()).is(esi)); 3698 ASSERT(ToRegister(instr->context()).is(esi));
3774 __ push(esi); // The context is the first argument. 3699 __ push(esi); // The context is the first argument.
3775 __ push(Immediate(instr->hydrogen()->pairs())); 3700 __ push(Immediate(instr->hydrogen()->pairs()));
3776 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); 3701 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3777 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3702 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3778 } 3703 }
3779 3704
3780 3705
3781 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3782 Register context = ToRegister(instr->context());
3783 Register result = ToRegister(instr->result());
3784 __ mov(result,
3785 Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3786 }
3787
3788
3789 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3790 Register global = ToRegister(instr->global());
3791 Register result = ToRegister(instr->result());
3792 __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset));
3793 }
3794
3795
3796 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3706 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3797 int formal_parameter_count, 3707 int formal_parameter_count,
3798 int arity, 3708 int arity,
3799 LInstruction* instr, 3709 LInstruction* instr,
3800 EDIState edi_state) { 3710 EDIState edi_state) {
3801 bool dont_adapt_arguments = 3711 bool dont_adapt_arguments =
3802 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3712 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3803 bool can_invoke_directly = 3713 bool can_invoke_directly =
3804 dont_adapt_arguments || formal_parameter_count == arity; 3714 dont_adapt_arguments || formal_parameter_count == arity;
3805 3715
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
4213 __ movsd(Operand(esp, 0), input_reg); 4123 __ movsd(Operand(esp, 0), input_reg);
4214 __ fld_d(Operand(esp, 0)); 4124 __ fld_d(Operand(esp, 0));
4215 __ fyl2x(); 4125 __ fyl2x();
4216 __ fstp_d(Operand(esp, 0)); 4126 __ fstp_d(Operand(esp, 0));
4217 __ movsd(input_reg, Operand(esp, 0)); 4127 __ movsd(input_reg, Operand(esp, 0));
4218 __ add(Operand(esp), Immediate(kDoubleSize)); 4128 __ add(Operand(esp), Immediate(kDoubleSize));
4219 __ bind(&done); 4129 __ bind(&done);
4220 } 4130 }
4221 4131
4222 4132
4133 void LCodeGen::DoMathClz32(LMathClz32* instr) {
4134 CpuFeatureScope scope(masm(), SSE2);
4135 Register input = ToRegister(instr->value());
4136 Register result = ToRegister(instr->result());
4137 Label not_zero_input;
4138 __ bsr(result, input);
4139
4140 __ j(not_zero, &not_zero_input);
4141 __ Set(result, Immediate(63)); // 63^31 == 32
4142
4143 __ bind(&not_zero_input);
4144 __ xor_(result, Immediate(31)); // for x in [0..31], 31^x == 31-x.
4145 }
4146
4147
4223 void LCodeGen::DoMathExp(LMathExp* instr) { 4148 void LCodeGen::DoMathExp(LMathExp* instr) {
4224 CpuFeatureScope scope(masm(), SSE2); 4149 CpuFeatureScope scope(masm(), SSE2);
4225 XMMRegister input = ToDoubleRegister(instr->value()); 4150 XMMRegister input = ToDoubleRegister(instr->value());
4226 XMMRegister result = ToDoubleRegister(instr->result()); 4151 XMMRegister result = ToDoubleRegister(instr->result());
4227 XMMRegister temp0 = double_scratch0(); 4152 XMMRegister temp0 = double_scratch0();
4228 Register temp1 = ToRegister(instr->temp1()); 4153 Register temp1 = ToRegister(instr->temp1());
4229 Register temp2 = ToRegister(instr->temp2()); 4154 Register temp2 = ToRegister(instr->temp2());
4230 4155
4231 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2); 4156 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2);
4232 } 4157 }
(...skipping 20 matching lines...) Expand all
4253 } 4178 }
4254 } 4179 }
4255 4180
4256 4181
4257 void LCodeGen::DoCallFunction(LCallFunction* instr) { 4182 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4258 ASSERT(ToRegister(instr->context()).is(esi)); 4183 ASSERT(ToRegister(instr->context()).is(esi));
4259 ASSERT(ToRegister(instr->function()).is(edi)); 4184 ASSERT(ToRegister(instr->function()).is(edi));
4260 ASSERT(ToRegister(instr->result()).is(eax)); 4185 ASSERT(ToRegister(instr->result()).is(eax));
4261 4186
4262 int arity = instr->arity(); 4187 int arity = instr->arity();
4263 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 4188 CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
4264 if (instr->hydrogen()->IsTailCall()) { 4189 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4265 if (NeedsEagerFrame()) __ leave();
4266 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
4267 } else {
4268 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4269 }
4270 } 4190 }
4271 4191
4272 4192
4273 void LCodeGen::DoCallNew(LCallNew* instr) { 4193 void LCodeGen::DoCallNew(LCallNew* instr) {
4274 ASSERT(ToRegister(instr->context()).is(esi)); 4194 ASSERT(ToRegister(instr->context()).is(esi));
4275 ASSERT(ToRegister(instr->constructor()).is(edi)); 4195 ASSERT(ToRegister(instr->constructor()).is(edi));
4276 ASSERT(ToRegister(instr->result()).is(eax)); 4196 ASSERT(ToRegister(instr->result()).is(eax));
4277 4197
4278 // No cell in ebx for construct type feedback in optimized code 4198 // No cell in ebx for construct type feedback in optimized code
4279 Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 4199 Handle<Object> undefined_value(isolate()->factory()->undefined_value());
4280 __ mov(ebx, Immediate(undefined_value)); 4200 __ mov(ebx, Immediate(undefined_value));
4281 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 4201 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
4282 __ Set(eax, Immediate(instr->arity())); 4202 __ Set(eax, Immediate(instr->arity()));
4283 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4203 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4284 } 4204 }
4285 4205
4286 4206
4287 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 4207 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4288 ASSERT(ToRegister(instr->context()).is(esi)); 4208 ASSERT(ToRegister(instr->context()).is(esi));
4289 ASSERT(ToRegister(instr->constructor()).is(edi)); 4209 ASSERT(ToRegister(instr->constructor()).is(edi));
4290 ASSERT(ToRegister(instr->result()).is(eax)); 4210 ASSERT(ToRegister(instr->result()).is(eax));
4291 4211
4292 __ Set(eax, Immediate(instr->arity())); 4212 __ Set(eax, Immediate(instr->arity()));
4293 __ mov(ebx, instr->hydrogen()->property_cell()); 4213 __ mov(ebx, factory()->undefined_value());
4294 ElementsKind kind = instr->hydrogen()->elements_kind(); 4214 ElementsKind kind = instr->hydrogen()->elements_kind();
4295 AllocationSiteOverrideMode override_mode = 4215 AllocationSiteOverrideMode override_mode =
4296 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 4216 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
4297 ? DISABLE_ALLOCATION_SITES 4217 ? DISABLE_ALLOCATION_SITES
4298 : DONT_OVERRIDE; 4218 : DONT_OVERRIDE;
4299 4219
4300 if (instr->arity() == 0) { 4220 if (instr->arity() == 0) {
4301 ArrayNoArgumentConstructorStub stub(kind, override_mode); 4221 ArrayNoArgumentConstructorStub stub(kind, override_mode);
4302 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4222 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4303 } else if (instr->arity() == 1) { 4223 } else if (instr->arity() == 1) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4371 __ mov(operand, Immediate(ToInteger32(operand_value))); 4291 __ mov(operand, Immediate(ToInteger32(operand_value)));
4372 } else { 4292 } else {
4373 Register value = ToRegister(instr->value()); 4293 Register value = ToRegister(instr->value());
4374 __ Store(value, operand, representation); 4294 __ Store(value, operand, representation);
4375 } 4295 }
4376 return; 4296 return;
4377 } 4297 }
4378 4298
4379 Register object = ToRegister(instr->object()); 4299 Register object = ToRegister(instr->object());
4380 Handle<Map> transition = instr->transition(); 4300 Handle<Map> transition = instr->transition();
4301 SmiCheck check_needed =
4302 instr->hydrogen()->value()->IsHeapObject()
4303 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4381 4304
4382 if (FLAG_track_fields && representation.IsSmi()) { 4305 if (FLAG_track_fields && representation.IsSmi()) {
4383 if (instr->value()->IsConstantOperand()) { 4306 if (instr->value()->IsConstantOperand()) {
4384 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4307 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4385 if (!IsSmi(operand_value)) { 4308 if (!IsSmi(operand_value)) {
4386 DeoptimizeIf(no_condition, instr->environment()); 4309 DeoptimizeIf(no_condition, instr->environment());
4387 } 4310 }
4388 } 4311 }
4389 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4312 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4390 if (instr->value()->IsConstantOperand()) { 4313 if (instr->value()->IsConstantOperand()) {
4391 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4314 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4392 if (IsInteger32(operand_value)) { 4315 if (IsInteger32(operand_value)) {
4393 DeoptimizeIf(no_condition, instr->environment()); 4316 DeoptimizeIf(no_condition, instr->environment());
4394 } 4317 }
4395 } else { 4318 } else {
4396 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4319 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4397 Register value = ToRegister(instr->value()); 4320 Register value = ToRegister(instr->value());
4398 __ test(value, Immediate(kSmiTagMask)); 4321 __ test(value, Immediate(kSmiTagMask));
4399 DeoptimizeIf(zero, instr->environment()); 4322 DeoptimizeIf(zero, instr->environment());
4323
4324 // We know that value is a smi now, so we can omit the check below.
4325 check_needed = OMIT_SMI_CHECK;
4400 } 4326 }
4401 } 4327 }
4402 } else if (FLAG_track_double_fields && representation.IsDouble()) { 4328 } else if (representation.IsDouble()) {
4403 ASSERT(transition.is_null()); 4329 ASSERT(transition.is_null());
4404 ASSERT(access.IsInobject()); 4330 ASSERT(access.IsInobject());
4405 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4331 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4406 if (CpuFeatures::IsSupported(SSE2)) { 4332 if (CpuFeatures::IsSupported(SSE2)) {
4407 CpuFeatureScope scope(masm(), SSE2); 4333 CpuFeatureScope scope(masm(), SSE2);
4408 XMMRegister value = ToDoubleRegister(instr->value()); 4334 XMMRegister value = ToDoubleRegister(instr->value());
4409 __ movsd(FieldOperand(object, offset), value); 4335 __ movsd(FieldOperand(object, offset), value);
4410 } else { 4336 } else {
4411 X87Register value = ToX87Register(instr->value()); 4337 X87Register value = ToX87Register(instr->value());
4412 X87Mov(FieldOperand(object, offset), value); 4338 X87Mov(FieldOperand(object, offset), value);
(...skipping 14 matching lines...) Expand all
4427 HeapObject::kMapOffset, 4353 HeapObject::kMapOffset,
4428 temp_map, 4354 temp_map,
4429 temp, 4355 temp,
4430 GetSaveFPRegsMode(), 4356 GetSaveFPRegsMode(),
4431 OMIT_REMEMBERED_SET, 4357 OMIT_REMEMBERED_SET,
4432 OMIT_SMI_CHECK); 4358 OMIT_SMI_CHECK);
4433 } 4359 }
4434 } 4360 }
4435 4361
4436 // Do the store. 4362 // Do the store.
4437 SmiCheck check_needed =
4438 instr->hydrogen()->value()->IsHeapObject()
4439 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4440
4441 Register write_register = object; 4363 Register write_register = object;
4442 if (!access.IsInobject()) { 4364 if (!access.IsInobject()) {
4443 write_register = ToRegister(instr->temp()); 4365 write_register = ToRegister(instr->temp());
4444 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 4366 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
4445 } 4367 }
4446 4368
4447 MemOperand operand = FieldOperand(write_register, offset); 4369 MemOperand operand = FieldOperand(write_register, offset);
4448 if (instr->value()->IsConstantOperand()) { 4370 if (instr->value()->IsConstantOperand()) {
4449 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4371 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4450 if (operand_value->IsRegister()) { 4372 if (operand_value->IsRegister()) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4531 elements_kind)) { 4453 elements_kind)) {
4532 __ SmiUntag(ToRegister(key)); 4454 __ SmiUntag(ToRegister(key));
4533 } 4455 }
4534 Operand operand(BuildFastArrayOperand( 4456 Operand operand(BuildFastArrayOperand(
4535 instr->elements(), 4457 instr->elements(),
4536 key, 4458 key,
4537 instr->hydrogen()->key()->representation(), 4459 instr->hydrogen()->key()->representation(),
4538 elements_kind, 4460 elements_kind,
4539 0, 4461 0,
4540 instr->additional_index())); 4462 instr->additional_index()));
4541 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4463 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4542 elements_kind == FLOAT32_ELEMENTS) { 4464 elements_kind == FLOAT32_ELEMENTS) {
4543 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4465 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4544 CpuFeatureScope scope(masm(), SSE2); 4466 CpuFeatureScope scope(masm(), SSE2);
4545 XMMRegister xmm_scratch = double_scratch0(); 4467 XMMRegister xmm_scratch = double_scratch0();
4546 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); 4468 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4547 __ movss(operand, xmm_scratch); 4469 __ movss(operand, xmm_scratch);
4548 } else { 4470 } else {
4549 __ fld(0); 4471 __ fld(0);
4550 __ fstp_s(operand); 4472 __ fstp_s(operand);
4551 } 4473 }
4552 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 4474 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
4553 elements_kind == FLOAT64_ELEMENTS) { 4475 elements_kind == FLOAT64_ELEMENTS) {
4554 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4476 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4555 CpuFeatureScope scope(masm(), SSE2); 4477 CpuFeatureScope scope(masm(), SSE2);
4556 __ movsd(operand, ToDoubleRegister(instr->value())); 4478 __ movsd(operand, ToDoubleRegister(instr->value()));
4557 } else { 4479 } else {
4558 X87Mov(operand, ToX87Register(instr->value())); 4480 X87Mov(operand, ToX87Register(instr->value()));
4559 } 4481 }
4560 } else { 4482 } else {
4561 Register value = ToRegister(instr->value()); 4483 Register value = ToRegister(instr->value());
4562 switch (elements_kind) { 4484 switch (elements_kind) {
4563 case EXTERNAL_PIXEL_ELEMENTS: 4485 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
4564 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4486 case EXTERNAL_UINT8_ELEMENTS:
4565 case EXTERNAL_BYTE_ELEMENTS: 4487 case EXTERNAL_INT8_ELEMENTS:
4566 case UINT8_ELEMENTS: 4488 case UINT8_ELEMENTS:
4567 case INT8_ELEMENTS: 4489 case INT8_ELEMENTS:
4568 case UINT8_CLAMPED_ELEMENTS: 4490 case UINT8_CLAMPED_ELEMENTS:
4569 __ mov_b(operand, value); 4491 __ mov_b(operand, value);
4570 break; 4492 break;
4571 case EXTERNAL_SHORT_ELEMENTS: 4493 case EXTERNAL_INT16_ELEMENTS:
4572 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4494 case EXTERNAL_UINT16_ELEMENTS:
4573 case UINT16_ELEMENTS: 4495 case UINT16_ELEMENTS:
4574 case INT16_ELEMENTS: 4496 case INT16_ELEMENTS:
4575 __ mov_w(operand, value); 4497 __ mov_w(operand, value);
4576 break; 4498 break;
4577 case EXTERNAL_INT_ELEMENTS: 4499 case EXTERNAL_INT32_ELEMENTS:
4578 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4500 case EXTERNAL_UINT32_ELEMENTS:
4579 case UINT32_ELEMENTS: 4501 case UINT32_ELEMENTS:
4580 case INT32_ELEMENTS: 4502 case INT32_ELEMENTS:
4581 __ mov(operand, value); 4503 __ mov(operand, value);
4582 break; 4504 break;
4583 case EXTERNAL_FLOAT_ELEMENTS: 4505 case EXTERNAL_FLOAT32_ELEMENTS:
4584 case EXTERNAL_DOUBLE_ELEMENTS: 4506 case EXTERNAL_FLOAT64_ELEMENTS:
4585 case FLOAT32_ELEMENTS: 4507 case FLOAT32_ELEMENTS:
4586 case FLOAT64_ELEMENTS: 4508 case FLOAT64_ELEMENTS:
4587 case FAST_SMI_ELEMENTS: 4509 case FAST_SMI_ELEMENTS:
4588 case FAST_ELEMENTS: 4510 case FAST_ELEMENTS:
4589 case FAST_DOUBLE_ELEMENTS: 4511 case FAST_DOUBLE_ELEMENTS:
4590 case FAST_HOLEY_SMI_ELEMENTS: 4512 case FAST_HOLEY_SMI_ELEMENTS:
4591 case FAST_HOLEY_ELEMENTS: 4513 case FAST_HOLEY_ELEMENTS:
4592 case FAST_HOLEY_DOUBLE_ELEMENTS: 4514 case FAST_HOLEY_DOUBLE_ELEMENTS:
4593 case DICTIONARY_ELEMENTS: 4515 case DICTIONARY_ELEMENTS:
4594 case NON_STRICT_ARGUMENTS_ELEMENTS: 4516 case NON_STRICT_ARGUMENTS_ELEMENTS:
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
4900 PushSafepointRegistersScope scope(this); 4822 PushSafepointRegistersScope scope(this);
4901 __ SmiTag(char_code); 4823 __ SmiTag(char_code);
4902 __ push(char_code); 4824 __ push(char_code);
4903 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); 4825 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4904 __ StoreToSafepointRegisterSlot(result, eax); 4826 __ StoreToSafepointRegisterSlot(result, eax);
4905 } 4827 }
4906 4828
4907 4829
4908 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4830 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4909 ASSERT(ToRegister(instr->context()).is(esi)); 4831 ASSERT(ToRegister(instr->context()).is(esi));
4910 if (FLAG_new_string_add) { 4832 ASSERT(ToRegister(instr->left()).is(edx));
4911 ASSERT(ToRegister(instr->left()).is(edx)); 4833 ASSERT(ToRegister(instr->right()).is(eax));
4912 ASSERT(ToRegister(instr->right()).is(eax)); 4834 StringAddStub stub(instr->hydrogen()->flags(),
4913 NewStringAddStub stub(instr->hydrogen()->flags(), 4835 instr->hydrogen()->pretenure_flag());
4914 instr->hydrogen()->pretenure_flag()); 4836 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4915 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4916 } else {
4917 EmitPushTaggedOperand(instr->left());
4918 EmitPushTaggedOperand(instr->right());
4919 StringAddStub stub(instr->hydrogen()->flags());
4920 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4921 }
4922 } 4837 }
4923 4838
4924 4839
4925 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4840 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4926 LOperand* input = instr->value(); 4841 LOperand* input = instr->value();
4927 LOperand* output = instr->result(); 4842 LOperand* output = instr->result();
4928 ASSERT(input->IsRegister() || input->IsStackSlot()); 4843 ASSERT(input->IsRegister() || input->IsStackSlot());
4929 ASSERT(output->IsDoubleRegister()); 4844 ASSERT(output->IsDoubleRegister());
4930 if (CpuFeatures::IsSupported(SSE2)) { 4845 if (CpuFeatures::IsSupported(SSE2)) {
4931 CpuFeatureScope scope(masm(), SSE2); 4846 CpuFeatureScope scope(masm(), SSE2);
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
5869 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5784 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5870 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5785 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5871 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5786 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
5872 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5787 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5873 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5788 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5874 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5789 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
5875 } 5790 }
5876 5791
5877 if (instr->size()->IsConstantOperand()) { 5792 if (instr->size()->IsConstantOperand()) {
5878 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5793 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5879 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 5794 if (size <= Page::kMaxRegularHeapObjectSize) {
5795 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
5796 } else {
5797 __ jmp(deferred->entry());
5798 }
5880 } else { 5799 } else {
5881 Register size = ToRegister(instr->size()); 5800 Register size = ToRegister(instr->size());
5882 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 5801 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
5883 } 5802 }
5884 5803
5885 __ bind(deferred->exit()); 5804 __ bind(deferred->exit());
5886 5805
5887 if (instr->hydrogen()->MustPrefillWithFiller()) { 5806 if (instr->hydrogen()->MustPrefillWithFiller()) {
5888 if (instr->size()->IsConstantOperand()) { 5807 if (instr->size()->IsConstantOperand()) {
5889 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5808 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
6362 FixedArray::kHeaderSize - kPointerSize)); 6281 FixedArray::kHeaderSize - kPointerSize));
6363 __ bind(&done); 6282 __ bind(&done);
6364 } 6283 }
6365 6284
6366 6285
6367 #undef __ 6286 #undef __
6368 6287
6369 } } // namespace v8::internal 6288 } } // namespace v8::internal
6370 6289
6371 #endif // V8_TARGET_ARCH_IA32 6290 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698