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

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

Issue 7132002: Remove RESTORE_CONTEXT flag from ia32 crankshaft codegen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Completed - use HContext everywhere except for HChange to tagged allocation. Created 9 years, 5 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 translation->StoreLiteral(src_index); 421 translation->StoreLiteral(src_index);
422 } else { 422 } else {
423 UNREACHABLE(); 423 UNREACHABLE();
424 } 424 }
425 } 425 }
426 426
427 427
428 void LCodeGen::CallCodeGeneric(Handle<Code> code, 428 void LCodeGen::CallCodeGeneric(Handle<Code> code,
429 RelocInfo::Mode mode, 429 RelocInfo::Mode mode,
430 LInstruction* instr, 430 LInstruction* instr,
431 ContextMode context_mode,
432 SafepointMode safepoint_mode) { 431 SafepointMode safepoint_mode) {
433 ASSERT(instr != NULL); 432 ASSERT(instr != NULL);
434 LPointerMap* pointers = instr->pointer_map(); 433 LPointerMap* pointers = instr->pointer_map();
435 RecordPosition(pointers->position()); 434 RecordPosition(pointers->position());
436 435
437 if (context_mode == RESTORE_CONTEXT) {
438 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
439 }
440 __ call(code, mode); 436 __ call(code, mode);
441 437
442 RegisterLazyDeoptimization(instr, safepoint_mode); 438 RegisterLazyDeoptimization(instr, safepoint_mode);
443 439
444 // Signal that we don't inline smi code before these stubs in the 440 // Signal that we don't inline smi code before these stubs in the
445 // optimizing code generator. 441 // optimizing code generator.
446 if (code->kind() == Code::BINARY_OP_IC || 442 if (code->kind() == Code::BINARY_OP_IC ||
447 code->kind() == Code::COMPARE_IC) { 443 code->kind() == Code::COMPARE_IC) {
448 __ nop(); 444 __ nop();
449 } 445 }
450 } 446 }
451 447
452 448
453 void LCodeGen::CallCode(Handle<Code> code, 449 void LCodeGen::CallCode(Handle<Code> code,
454 RelocInfo::Mode mode, 450 RelocInfo::Mode mode,
455 LInstruction* instr, 451 LInstruction* instr) {
456 ContextMode context_mode) { 452 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
457 CallCodeGeneric(code, mode, instr, context_mode, RECORD_SIMPLE_SAFEPOINT);
458 } 453 }
459 454
460 455
461 void LCodeGen::CallRuntime(const Runtime::Function* fun, 456 void LCodeGen::CallRuntime(const Runtime::Function* fun,
462 int argc, 457 int argc,
463 LInstruction* instr, 458 LInstruction* instr) {
464 ContextMode context_mode) {
465 ASSERT(instr != NULL); 459 ASSERT(instr != NULL);
466 ASSERT(instr->HasPointerMap()); 460 ASSERT(instr->HasPointerMap());
467 LPointerMap* pointers = instr->pointer_map(); 461 LPointerMap* pointers = instr->pointer_map();
468 RecordPosition(pointers->position()); 462 RecordPosition(pointers->position());
469 463
470 if (context_mode == RESTORE_CONTEXT) {
471 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
472 }
473 __ CallRuntime(fun, argc); 464 __ CallRuntime(fun, argc);
474 465
475 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); 466 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
476 } 467 }
477 468
478 469
479 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 470 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
480 int argc, 471 int argc,
481 LInstruction* instr) { 472 LInstruction* instr,
482 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 473 LOperand* context) {
474 ASSERT(context->IsRegister() || context->IsStackSlot());
475 if (context->IsRegister()) {
476 if (!ToRegister(context).is(esi)) {
477 __ mov(esi, ToRegister(context));
478 }
479 } else {
480 // Context is stack slot.
481 __ mov(esi, ToOperand(context));
482 }
483
483 __ CallRuntimeSaveDoubles(id); 484 __ CallRuntimeSaveDoubles(id);
484 RecordSafepointWithRegisters( 485 RecordSafepointWithRegisters(
485 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); 486 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
486 } 487 }
487 488
488 489
489 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr, 490 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr,
490 SafepointMode safepoint_mode) { 491 SafepointMode safepoint_mode) {
491 // Create the environment to bailout to. If the call has side effects 492 // Create the environment to bailout to. If the call has side effects
492 // execution has to continue after the call otherwise execution can continue 493 // execution has to continue after the call otherwise execution can continue
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 // Nothing to do. 742 // Nothing to do.
742 } 743 }
743 744
744 745
745 void LCodeGen::DoCallStub(LCallStub* instr) { 746 void LCodeGen::DoCallStub(LCallStub* instr) {
746 ASSERT(ToRegister(instr->context()).is(esi)); 747 ASSERT(ToRegister(instr->context()).is(esi));
747 ASSERT(ToRegister(instr->result()).is(eax)); 748 ASSERT(ToRegister(instr->result()).is(eax));
748 switch (instr->hydrogen()->major_key()) { 749 switch (instr->hydrogen()->major_key()) {
749 case CodeStub::RegExpConstructResult: { 750 case CodeStub::RegExpConstructResult: {
750 RegExpConstructResultStub stub; 751 RegExpConstructResultStub stub;
751 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 752 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
752 break; 753 break;
753 } 754 }
754 case CodeStub::RegExpExec: { 755 case CodeStub::RegExpExec: {
755 RegExpExecStub stub; 756 RegExpExecStub stub;
756 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 757 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
757 break; 758 break;
758 } 759 }
759 case CodeStub::SubString: { 760 case CodeStub::SubString: {
760 SubStringStub stub; 761 SubStringStub stub;
761 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 762 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
762 break; 763 break;
763 } 764 }
764 case CodeStub::NumberToString: { 765 case CodeStub::NumberToString: {
765 NumberToStringStub stub; 766 NumberToStringStub stub;
766 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 767 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
767 break; 768 break;
768 } 769 }
769 case CodeStub::StringAdd: { 770 case CodeStub::StringAdd: {
770 StringAddStub stub(NO_STRING_ADD_FLAGS); 771 StringAddStub stub(NO_STRING_ADD_FLAGS);
771 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 772 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
772 break; 773 break;
773 } 774 }
774 case CodeStub::StringCompare: { 775 case CodeStub::StringCompare: {
775 StringCompareStub stub; 776 StringCompareStub stub;
776 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 777 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
777 break; 778 break;
778 } 779 }
779 case CodeStub::TranscendentalCache: { 780 case CodeStub::TranscendentalCache: {
780 TranscendentalCacheStub stub(instr->transcendental_type(), 781 TranscendentalCacheStub stub(instr->transcendental_type(),
781 TranscendentalCacheStub::TAGGED); 782 TranscendentalCacheStub::TAGGED);
782 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 783 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
783 break; 784 break;
784 } 785 }
785 default: 786 default:
786 UNREACHABLE(); 787 UNREACHABLE();
787 } 788 }
788 } 789 }
789 790
790 791
791 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 792 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
792 // Nothing to do. 793 // Nothing to do.
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 1250
1250 1251
1251 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1252 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1252 LOperand* input = instr->InputAt(0); 1253 LOperand* input = instr->InputAt(0);
1253 ASSERT(input->Equals(instr->result())); 1254 ASSERT(input->Equals(instr->result()));
1254 __ not_(ToRegister(input)); 1255 __ not_(ToRegister(input));
1255 } 1256 }
1256 1257
1257 1258
1258 void LCodeGen::DoThrow(LThrow* instr) { 1259 void LCodeGen::DoThrow(LThrow* instr) {
1259 __ push(ToOperand(instr->InputAt(0))); 1260 __ push(ToOperand(instr->value()));
1260 CallRuntime(Runtime::kThrow, 1, instr, RESTORE_CONTEXT); 1261 ASSERT(ToRegister(instr->context()).is(esi));
1262 CallRuntime(Runtime::kThrow, 1, instr);
1261 1263
1262 if (FLAG_debug_code) { 1264 if (FLAG_debug_code) {
1263 Comment("Unreachable code."); 1265 Comment("Unreachable code.");
1264 __ int3(); 1266 __ int3();
1265 } 1267 }
1266 } 1268 }
1267 1269
1268 1270
1269 void LCodeGen::DoAddI(LAddI* instr) { 1271 void LCodeGen::DoAddI(LAddI* instr) {
1270 LOperand* left = instr->InputAt(0); 1272 LOperand* left = instr->InputAt(0);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 break; 1322 break;
1321 } 1323 }
1322 default: 1324 default:
1323 UNREACHABLE(); 1325 UNREACHABLE();
1324 break; 1326 break;
1325 } 1327 }
1326 } 1328 }
1327 1329
1328 1330
1329 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1331 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1330 ASSERT(ToRegister(instr->InputAt(0)).is(edx)); 1332 ASSERT(ToRegister(instr->context()).is(esi));
1331 ASSERT(ToRegister(instr->InputAt(1)).is(eax)); 1333 ASSERT(ToRegister(instr->left()).is(edx));
1334 ASSERT(ToRegister(instr->right()).is(eax));
1332 ASSERT(ToRegister(instr->result()).is(eax)); 1335 ASSERT(ToRegister(instr->result()).is(eax));
1333 1336
1334 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1337 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1335 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 1338 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1336 } 1339 }
1337 1340
1338 1341
1339 int LCodeGen::GetNextEmittedBlock(int block) { 1342 int LCodeGen::GetNextEmittedBlock(int block) {
1340 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1343 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
1341 LLabel* label = chunk_->GetLabel(i); 1344 LLabel* label = chunk_->GetLabel(i);
1342 if (!label->HasReplacement()) return i; 1345 if (!label->HasReplacement()) return i;
1343 } 1346 }
1344 return -1; 1347 return -1;
1345 } 1348 }
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 1968
1966 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 1969 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
1967 EmitBranch(true_block, false_block, equal); 1970 EmitBranch(true_block, false_block, equal);
1968 } 1971 }
1969 1972
1970 1973
1971 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1974 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1972 // Object and function are in fixed registers defined by the stub. 1975 // Object and function are in fixed registers defined by the stub.
1973 ASSERT(ToRegister(instr->context()).is(esi)); 1976 ASSERT(ToRegister(instr->context()).is(esi));
1974 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 1977 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1975 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 1978 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1976 1979
1977 Label true_value, done; 1980 Label true_value, done;
1978 __ test(eax, Operand(eax)); 1981 __ test(eax, Operand(eax));
1979 __ j(zero, &true_value, Label::kNear); 1982 __ j(zero, &true_value, Label::kNear);
1980 __ mov(ToRegister(instr->result()), factory()->false_value()); 1983 __ mov(ToRegister(instr->result()), factory()->false_value());
1981 __ jmp(&done, Label::kNear); 1984 __ jmp(&done, Label::kNear);
1982 __ bind(&true_value); 1985 __ bind(&true_value);
1983 __ mov(ToRegister(instr->result()), factory()->true_value()); 1986 __ mov(ToRegister(instr->result()), factory()->true_value());
1984 __ bind(&done); 1987 __ bind(&done);
1985 } 1988 }
(...skipping 13 matching lines...) Expand all
1999 2002
2000 private: 2003 private:
2001 LInstanceOfKnownGlobal* instr_; 2004 LInstanceOfKnownGlobal* instr_;
2002 Label map_check_; 2005 Label map_check_;
2003 }; 2006 };
2004 2007
2005 DeferredInstanceOfKnownGlobal* deferred; 2008 DeferredInstanceOfKnownGlobal* deferred;
2006 deferred = new DeferredInstanceOfKnownGlobal(this, instr); 2009 deferred = new DeferredInstanceOfKnownGlobal(this, instr);
2007 2010
2008 Label done, false_result; 2011 Label done, false_result;
2009 Register object = ToRegister(instr->InputAt(0)); 2012 Register object = ToRegister(instr->InputAt(1));
2010 Register temp = ToRegister(instr->TempAt(0)); 2013 Register temp = ToRegister(instr->TempAt(0));
2011 2014
2012 // A Smi is not an instance of anything. 2015 // A Smi is not an instance of anything.
2013 __ JumpIfSmi(object, &false_result); 2016 __ JumpIfSmi(object, &false_result);
2014 2017
2015 // This is the inlined call site instanceof cache. The two occurences of the 2018 // This is the inlined call site instanceof cache. The two occurences of the
2016 // hole value will be patched to the last map/result pair generated by the 2019 // hole value will be patched to the last map/result pair generated by the
2017 // instanceof stub. 2020 // instanceof stub.
2018 Label cache_miss; 2021 Label cache_miss;
2019 Register map = ToRegister(instr->TempAt(0)); 2022 Register map = ToRegister(instr->TempAt(0));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 flags | InstanceofStub::kReturnTrueFalseObject); 2064 flags | InstanceofStub::kReturnTrueFalseObject);
2062 InstanceofStub stub(flags); 2065 InstanceofStub stub(flags);
2063 2066
2064 // Get the temp register reserved by the instruction. This needs to be a 2067 // Get the temp register reserved by the instruction. This needs to be a
2065 // register which is pushed last by PushSafepointRegisters as top of the 2068 // register which is pushed last by PushSafepointRegisters as top of the
2066 // stack is used to pass the offset to the location of the map check to 2069 // stack is used to pass the offset to the location of the map check to
2067 // the stub. 2070 // the stub.
2068 Register temp = ToRegister(instr->TempAt(0)); 2071 Register temp = ToRegister(instr->TempAt(0));
2069 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 2072 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
2070 __ mov(InstanceofStub::right(), Immediate(instr->function())); 2073 __ mov(InstanceofStub::right(), Immediate(instr->function()));
2071 static const int kAdditionalDelta = 16; 2074 static const int kAdditionalDelta = 13;
2072 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2075 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2073 __ mov(temp, Immediate(delta)); 2076 __ mov(temp, Immediate(delta));
2074 __ StoreToSafepointRegisterSlot(temp, temp); 2077 __ StoreToSafepointRegisterSlot(temp, temp);
2075 CallCodeGeneric(stub.GetCode(), 2078 CallCodeGeneric(stub.GetCode(),
2076 RelocInfo::CODE_TARGET, 2079 RelocInfo::CODE_TARGET,
2077 instr, 2080 instr,
2078 RESTORE_CONTEXT,
2079 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 2081 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
2080 // Put the result value into the eax slot and restore all registers. 2082 // Put the result value into the eax slot and restore all registers.
2081 __ StoreToSafepointRegisterSlot(eax, eax); 2083 __ StoreToSafepointRegisterSlot(eax, eax);
2082 } 2084 }
2083 2085
2084 2086
2085 static Condition ComputeCompareCondition(Token::Value op) { 2087 static Condition ComputeCompareCondition(Token::Value op) {
2086 switch (op) { 2088 switch (op) {
2087 case Token::EQ_STRICT: 2089 case Token::EQ_STRICT:
2088 case Token::EQ: 2090 case Token::EQ:
(...skipping 10 matching lines...) Expand all
2099 UNREACHABLE(); 2101 UNREACHABLE();
2100 return no_condition; 2102 return no_condition;
2101 } 2103 }
2102 } 2104 }
2103 2105
2104 2106
2105 void LCodeGen::DoCmpT(LCmpT* instr) { 2107 void LCodeGen::DoCmpT(LCmpT* instr) {
2106 Token::Value op = instr->op(); 2108 Token::Value op = instr->op();
2107 2109
2108 Handle<Code> ic = CompareIC::GetUninitialized(op); 2110 Handle<Code> ic = CompareIC::GetUninitialized(op);
2109 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 2111 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2110 2112
2111 Condition condition = ComputeCompareCondition(op); 2113 Condition condition = ComputeCompareCondition(op);
2112 if (op == Token::GT || op == Token::LTE) { 2114 if (op == Token::GT || op == Token::LTE) {
2113 condition = ReverseCondition(condition); 2115 condition = ReverseCondition(condition);
2114 } 2116 }
2115 Label true_value, done; 2117 Label true_value, done;
2116 __ test(eax, Operand(eax)); 2118 __ test(eax, Operand(eax));
2117 __ j(condition, &true_value, Label::kNear); 2119 __ j(condition, &true_value, Label::kNear);
2118 __ mov(ToRegister(instr->result()), factory()->false_value()); 2120 __ mov(ToRegister(instr->result()), factory()->false_value());
2119 __ jmp(&done, Label::kNear); 2121 __ jmp(&done, Label::kNear);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 2153
2152 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 2154 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2153 ASSERT(ToRegister(instr->context()).is(esi)); 2155 ASSERT(ToRegister(instr->context()).is(esi));
2154 ASSERT(ToRegister(instr->global_object()).is(eax)); 2156 ASSERT(ToRegister(instr->global_object()).is(eax));
2155 ASSERT(ToRegister(instr->result()).is(eax)); 2157 ASSERT(ToRegister(instr->result()).is(eax));
2156 2158
2157 __ mov(ecx, instr->name()); 2159 __ mov(ecx, instr->name());
2158 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : 2160 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
2159 RelocInfo::CODE_TARGET_CONTEXT; 2161 RelocInfo::CODE_TARGET_CONTEXT;
2160 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2162 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2161 CallCode(ic, mode, instr, CONTEXT_ADJUSTED); 2163 CallCode(ic, mode, instr);
2162 } 2164 }
2163 2165
2164 2166
2165 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2167 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2166 Register value = ToRegister(instr->InputAt(0)); 2168 Register value = ToRegister(instr->InputAt(0));
2167 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell()); 2169 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell());
2168 2170
2169 // If the cell we are storing to contains the hole it could have 2171 // If the cell we are storing to contains the hole it could have
2170 // been deleted from the property dictionary. In that case, we need 2172 // been deleted from the property dictionary. In that case, we need
2171 // to update the property details in the property dictionary to mark 2173 // to update the property details in the property dictionary to mark
(...skipping 10 matching lines...) Expand all
2182 2184
2183 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 2185 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2184 ASSERT(ToRegister(instr->context()).is(esi)); 2186 ASSERT(ToRegister(instr->context()).is(esi));
2185 ASSERT(ToRegister(instr->global_object()).is(edx)); 2187 ASSERT(ToRegister(instr->global_object()).is(edx));
2186 ASSERT(ToRegister(instr->value()).is(eax)); 2188 ASSERT(ToRegister(instr->value()).is(eax));
2187 2189
2188 __ mov(ecx, instr->name()); 2190 __ mov(ecx, instr->name());
2189 Handle<Code> ic = instr->strict_mode() 2191 Handle<Code> ic = instr->strict_mode()
2190 ? isolate()->builtins()->StoreIC_Initialize_Strict() 2192 ? isolate()->builtins()->StoreIC_Initialize_Strict()
2191 : isolate()->builtins()->StoreIC_Initialize(); 2193 : isolate()->builtins()->StoreIC_Initialize();
2192 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED); 2194 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2193 } 2195 }
2194 2196
2195 2197
2196 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2198 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2197 Register context = ToRegister(instr->context()); 2199 Register context = ToRegister(instr->context());
2198 Register result = ToRegister(instr->result()); 2200 Register result = ToRegister(instr->result());
2199 __ mov(result, ContextOperand(context, instr->slot_index())); 2201 __ mov(result, ContextOperand(context, instr->slot_index()));
2200 } 2202 }
2201 2203
2202 2204
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { 2256 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2255 Register object = ToRegister(instr->object()); 2257 Register object = ToRegister(instr->object());
2256 Register result = ToRegister(instr->result()); 2258 Register result = ToRegister(instr->result());
2257 2259
2258 int map_count = instr->hydrogen()->types()->length(); 2260 int map_count = instr->hydrogen()->types()->length();
2259 Handle<String> name = instr->hydrogen()->name(); 2261 Handle<String> name = instr->hydrogen()->name();
2260 if (map_count == 0) { 2262 if (map_count == 0) {
2261 ASSERT(instr->hydrogen()->need_generic()); 2263 ASSERT(instr->hydrogen()->need_generic());
2262 __ mov(ecx, name); 2264 __ mov(ecx, name);
2263 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2265 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2264 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 2266 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2265 } else { 2267 } else {
2266 Label done; 2268 Label done;
2267 for (int i = 0; i < map_count - 1; ++i) { 2269 for (int i = 0; i < map_count - 1; ++i) {
2268 Handle<Map> map = instr->hydrogen()->types()->at(i); 2270 Handle<Map> map = instr->hydrogen()->types()->at(i);
2269 Label next; 2271 Label next;
2270 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); 2272 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2271 __ j(not_equal, &next, Label::kNear); 2273 __ j(not_equal, &next, Label::kNear);
2272 EmitLoadFieldOrConstantFunction(result, object, map, name); 2274 EmitLoadFieldOrConstantFunction(result, object, map, name);
2273 __ jmp(&done, Label::kNear); 2275 __ jmp(&done, Label::kNear);
2274 __ bind(&next); 2276 __ bind(&next);
2275 } 2277 }
2276 Handle<Map> map = instr->hydrogen()->types()->last(); 2278 Handle<Map> map = instr->hydrogen()->types()->last();
2277 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); 2279 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2278 if (instr->hydrogen()->need_generic()) { 2280 if (instr->hydrogen()->need_generic()) {
2279 Label generic; 2281 Label generic;
2280 __ j(not_equal, &generic, Label::kNear); 2282 __ j(not_equal, &generic, Label::kNear);
2281 EmitLoadFieldOrConstantFunction(result, object, map, name); 2283 EmitLoadFieldOrConstantFunction(result, object, map, name);
2282 __ jmp(&done, Label::kNear); 2284 __ jmp(&done, Label::kNear);
2283 __ bind(&generic); 2285 __ bind(&generic);
2284 __ mov(ecx, name); 2286 __ mov(ecx, name);
2285 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2287 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2286 CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 2288 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2287 } else { 2289 } else {
2288 DeoptimizeIf(not_equal, instr->environment()); 2290 DeoptimizeIf(not_equal, instr->environment());
2289 EmitLoadFieldOrConstantFunction(result, object, map, name); 2291 EmitLoadFieldOrConstantFunction(result, object, map, name);
2290 } 2292 }
2291 __ bind(&done); 2293 __ bind(&done);
2292 } 2294 }
2293 } 2295 }
2294 2296
2295 2297
2296 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 2298 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2297 ASSERT(ToRegister(instr->context()).is(esi)); 2299 ASSERT(ToRegister(instr->context()).is(esi));
2298 ASSERT(ToRegister(instr->object()).is(eax)); 2300 ASSERT(ToRegister(instr->object()).is(eax));
2299 ASSERT(ToRegister(instr->result()).is(eax)); 2301 ASSERT(ToRegister(instr->result()).is(eax));
2300 2302
2301 __ mov(ecx, instr->name()); 2303 __ mov(ecx, instr->name());
2302 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2304 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2303 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 2305 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2304 } 2306 }
2305 2307
2306 2308
2307 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 2309 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2308 Register function = ToRegister(instr->function()); 2310 Register function = ToRegister(instr->function());
2309 Register temp = ToRegister(instr->TempAt(0)); 2311 Register temp = ToRegister(instr->TempAt(0));
2310 Register result = ToRegister(instr->result()); 2312 Register result = ToRegister(instr->result());
2311 2313
2312 // Check that the function really is a function. 2314 // Check that the function really is a function.
2313 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); 2315 __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 } 2494 }
2493 } 2495 }
2494 2496
2495 2497
2496 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2498 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2497 ASSERT(ToRegister(instr->context()).is(esi)); 2499 ASSERT(ToRegister(instr->context()).is(esi));
2498 ASSERT(ToRegister(instr->object()).is(edx)); 2500 ASSERT(ToRegister(instr->object()).is(edx));
2499 ASSERT(ToRegister(instr->key()).is(eax)); 2501 ASSERT(ToRegister(instr->key()).is(eax));
2500 2502
2501 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2503 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2502 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 2504 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2503 } 2505 }
2504 2506
2505 2507
2506 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 2508 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
2507 Register result = ToRegister(instr->result()); 2509 Register result = ToRegister(instr->result());
2508 2510
2509 // Check for arguments adapter frame. 2511 // Check for arguments adapter frame.
2510 Label done, adapted; 2512 Label done, adapted;
2511 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2513 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2512 __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); 2514 __ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2722 ASSERT(ToRegister(instr->result()).is(eax)); 2724 ASSERT(ToRegister(instr->result()).is(eax));
2723 __ mov(edi, instr->function()); 2725 __ mov(edi, instr->function());
2724 CallKnownFunction(instr->function(), 2726 CallKnownFunction(instr->function(),
2725 instr->arity(), 2727 instr->arity(),
2726 instr, 2728 instr,
2727 CALL_AS_METHOD); 2729 CALL_AS_METHOD);
2728 } 2730 }
2729 2731
2730 2732
2731 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2733 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2732 Register input_reg = ToRegister(instr->InputAt(0)); 2734 Register input_reg = ToRegister(instr->value());
2733 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 2735 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
2734 factory()->heap_number_map()); 2736 factory()->heap_number_map());
2735 DeoptimizeIf(not_equal, instr->environment()); 2737 DeoptimizeIf(not_equal, instr->environment());
2736 2738
2737 Label done; 2739 Label done;
2738 Register tmp = input_reg.is(eax) ? ecx : eax; 2740 Register tmp = input_reg.is(eax) ? ecx : eax;
2739 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; 2741 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx;
2740 2742
2741 // Preserve the value of all registers. 2743 // Preserve the value of all registers.
2742 PushSafepointRegistersScope scope(this); 2744 PushSafepointRegistersScope scope(this);
(...skipping 10 matching lines...) Expand all
2753 2755
2754 __ bind(&negative); 2756 __ bind(&negative);
2755 2757
2756 Label allocated, slow; 2758 Label allocated, slow;
2757 __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); 2759 __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow);
2758 __ jmp(&allocated); 2760 __ jmp(&allocated);
2759 2761
2760 // Slow case: Call the runtime system to do the number allocation. 2762 // Slow case: Call the runtime system to do the number allocation.
2761 __ bind(&slow); 2763 __ bind(&slow);
2762 2764
2763 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 2765 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0,
2766 instr, instr->context());
2764 2767
2765 // Set the pointer to the new heap number in tmp. 2768 // Set the pointer to the new heap number in tmp.
2766 if (!tmp.is(eax)) __ mov(tmp, eax); 2769 if (!tmp.is(eax)) __ mov(tmp, eax);
2767 2770
2768 // Restore input_reg after call to runtime. 2771 // Restore input_reg after call to runtime.
2769 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 2772 __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
2770 2773
2771 __ bind(&allocated); 2774 __ bind(&allocated);
2772 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 2775 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset));
2773 __ and_(tmp2, ~HeapNumber::kSignMask); 2776 __ and_(tmp2, ~HeapNumber::kSignMask);
2774 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); 2777 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2);
2775 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 2778 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
2776 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); 2779 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2);
2777 __ StoreToSafepointRegisterSlot(input_reg, tmp); 2780 __ StoreToSafepointRegisterSlot(input_reg, tmp);
2778 2781
2779 __ bind(&done); 2782 __ bind(&done);
2780 } 2783 }
2781 2784
2782 2785
2783 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2786 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2784 Register input_reg = ToRegister(instr->InputAt(0)); 2787 Register input_reg = ToRegister(instr->value());
2785 __ test(input_reg, Operand(input_reg)); 2788 __ test(input_reg, Operand(input_reg));
2786 Label is_positive; 2789 Label is_positive;
2787 __ j(not_sign, &is_positive); 2790 __ j(not_sign, &is_positive);
2788 __ neg(input_reg); 2791 __ neg(input_reg);
2789 __ test(input_reg, Operand(input_reg)); 2792 __ test(input_reg, Operand(input_reg));
2790 DeoptimizeIf(negative, instr->environment()); 2793 DeoptimizeIf(negative, instr->environment());
2791 __ bind(&is_positive); 2794 __ bind(&is_positive);
2792 } 2795 }
2793 2796
2794 2797
2795 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2798 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2796 // Class for deferred case. 2799 // Class for deferred case.
2797 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2800 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2798 public: 2801 public:
2799 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2802 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2800 LUnaryMathOperation* instr) 2803 LUnaryMathOperation* instr)
2801 : LDeferredCode(codegen), instr_(instr) { } 2804 : LDeferredCode(codegen), instr_(instr) { }
2802 virtual void Generate() { 2805 virtual void Generate() {
2803 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2806 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2804 } 2807 }
2805 private: 2808 private:
2806 LUnaryMathOperation* instr_; 2809 LUnaryMathOperation* instr_;
2807 }; 2810 };
2808 2811
2809 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2812 ASSERT(instr->value()->Equals(instr->result()));
2810 Representation r = instr->hydrogen()->value()->representation(); 2813 Representation r = instr->hydrogen()->value()->representation();
2811 2814
2812 if (r.IsDouble()) { 2815 if (r.IsDouble()) {
2813 XMMRegister scratch = xmm0; 2816 XMMRegister scratch = xmm0;
2814 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2817 XMMRegister input_reg = ToDoubleRegister(instr->value());
2815 __ xorps(scratch, scratch); 2818 __ xorps(scratch, scratch);
2816 __ subsd(scratch, input_reg); 2819 __ subsd(scratch, input_reg);
2817 __ pand(input_reg, scratch); 2820 __ pand(input_reg, scratch);
2818 } else if (r.IsInteger32()) { 2821 } else if (r.IsInteger32()) {
2819 EmitIntegerMathAbs(instr); 2822 EmitIntegerMathAbs(instr);
2820 } else { // Tagged case. 2823 } else { // Tagged case.
2821 DeferredMathAbsTaggedHeapNumber* deferred = 2824 DeferredMathAbsTaggedHeapNumber* deferred =
2822 new DeferredMathAbsTaggedHeapNumber(this, instr); 2825 new DeferredMathAbsTaggedHeapNumber(this, instr);
2823 Register input_reg = ToRegister(instr->InputAt(0)); 2826 Register input_reg = ToRegister(instr->value());
2824 // Smi check. 2827 // Smi check.
2825 __ JumpIfNotSmi(input_reg, deferred->entry()); 2828 __ JumpIfNotSmi(input_reg, deferred->entry());
2826 EmitIntegerMathAbs(instr); 2829 EmitIntegerMathAbs(instr);
2827 __ bind(deferred->exit()); 2830 __ bind(deferred->exit());
2828 } 2831 }
2829 } 2832 }
2830 2833
2831 2834
2832 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2835 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2833 XMMRegister xmm_scratch = xmm0; 2836 XMMRegister xmm_scratch = xmm0;
2834 Register output_reg = ToRegister(instr->result()); 2837 Register output_reg = ToRegister(instr->result());
2835 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2838 XMMRegister input_reg = ToDoubleRegister(instr->value());
2836 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 2839 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2837 __ ucomisd(input_reg, xmm_scratch); 2840 __ ucomisd(input_reg, xmm_scratch);
2838 2841
2839 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2842 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2840 DeoptimizeIf(below_equal, instr->environment()); 2843 DeoptimizeIf(below_equal, instr->environment());
2841 } else { 2844 } else {
2842 DeoptimizeIf(below, instr->environment()); 2845 DeoptimizeIf(below, instr->environment());
2843 } 2846 }
2844 2847
2845 // Use truncating instruction (OK because input is positive). 2848 // Use truncating instruction (OK because input is positive).
2846 __ cvttsd2si(output_reg, Operand(input_reg)); 2849 __ cvttsd2si(output_reg, Operand(input_reg));
2847 2850
2848 // Overflow is signalled with minint. 2851 // Overflow is signalled with minint.
2849 __ cmp(output_reg, 0x80000000u); 2852 __ cmp(output_reg, 0x80000000u);
2850 DeoptimizeIf(equal, instr->environment()); 2853 DeoptimizeIf(equal, instr->environment());
2851 } 2854 }
2852 2855
2853 2856
2854 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2857 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2855 XMMRegister xmm_scratch = xmm0; 2858 XMMRegister xmm_scratch = xmm0;
2856 Register output_reg = ToRegister(instr->result()); 2859 Register output_reg = ToRegister(instr->result());
2857 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2860 XMMRegister input_reg = ToDoubleRegister(instr->value());
2858 2861
2859 Label below_half, done; 2862 Label below_half, done;
2860 // xmm_scratch = 0.5 2863 // xmm_scratch = 0.5
2861 ExternalReference one_half = ExternalReference::address_of_one_half(); 2864 ExternalReference one_half = ExternalReference::address_of_one_half();
2862 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 2865 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
2863 2866
2864 __ ucomisd(xmm_scratch, input_reg); 2867 __ ucomisd(xmm_scratch, input_reg);
2865 __ j(above, &below_half); 2868 __ j(above, &below_half);
2866 // input = input + 0.5 2869 // input = input + 0.5
2867 __ addsd(input_reg, xmm_scratch); 2870 __ addsd(input_reg, xmm_scratch);
(...skipping 24 matching lines...) Expand all
2892 __ cvtss2sd(xmm_scratch, xmm_scratch); 2895 __ cvtss2sd(xmm_scratch, xmm_scratch);
2893 __ ucomisd(input_reg, xmm_scratch); 2896 __ ucomisd(input_reg, xmm_scratch);
2894 DeoptimizeIf(below, instr->environment()); 2897 DeoptimizeIf(below, instr->environment());
2895 } 2898 }
2896 __ Set(output_reg, Immediate(0)); 2899 __ Set(output_reg, Immediate(0));
2897 __ bind(&done); 2900 __ bind(&done);
2898 } 2901 }
2899 2902
2900 2903
2901 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2904 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2902 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2905 XMMRegister input_reg = ToDoubleRegister(instr->value());
2903 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2906 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2904 __ sqrtsd(input_reg, input_reg); 2907 __ sqrtsd(input_reg, input_reg);
2905 } 2908 }
2906 2909
2907 2910
2908 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 2911 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2909 XMMRegister xmm_scratch = xmm0; 2912 XMMRegister xmm_scratch = xmm0;
2910 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2913 XMMRegister input_reg = ToDoubleRegister(instr->value());
2911 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2914 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2912 __ xorps(xmm_scratch, xmm_scratch); 2915 __ xorps(xmm_scratch, xmm_scratch);
2913 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 2916 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
2914 __ sqrtsd(input_reg, input_reg); 2917 __ sqrtsd(input_reg, input_reg);
2915 } 2918 }
2916 2919
2917 2920
2918 void LCodeGen::DoPower(LPower* instr) { 2921 void LCodeGen::DoPower(LPower* instr) {
2919 LOperand* left = instr->InputAt(0); 2922 LOperand* left = instr->InputAt(0);
2920 LOperand* right = instr->InputAt(1); 2923 LOperand* right = instr->InputAt(1);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2968 // Return value is in st(0) on ia32. 2971 // Return value is in st(0) on ia32.
2969 // Store it into the (fixed) result register. 2972 // Store it into the (fixed) result register.
2970 __ sub(Operand(esp), Immediate(kDoubleSize)); 2973 __ sub(Operand(esp), Immediate(kDoubleSize));
2971 __ fstp_d(Operand(esp, 0)); 2974 __ fstp_d(Operand(esp, 0));
2972 __ movdbl(result_reg, Operand(esp, 0)); 2975 __ movdbl(result_reg, Operand(esp, 0));
2973 __ add(Operand(esp), Immediate(kDoubleSize)); 2976 __ add(Operand(esp), Immediate(kDoubleSize));
2974 } 2977 }
2975 2978
2976 2979
2977 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 2980 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2978 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2981 ASSERT(instr->value()->Equals(instr->result()));
2979 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2982 XMMRegister input_reg = ToDoubleRegister(instr->value());
2980 Label positive, done, zero; 2983 Label positive, done, zero;
2981 __ xorps(xmm0, xmm0); 2984 __ xorps(xmm0, xmm0);
2982 __ ucomisd(input_reg, xmm0); 2985 __ ucomisd(input_reg, xmm0);
2983 __ j(above, &positive, Label::kNear); 2986 __ j(above, &positive, Label::kNear);
2984 __ j(equal, &zero, Label::kNear); 2987 __ j(equal, &zero, Label::kNear);
2985 ExternalReference nan = ExternalReference::address_of_nan(); 2988 ExternalReference nan = ExternalReference::address_of_nan();
2986 __ movdbl(input_reg, Operand::StaticVariable(nan)); 2989 __ movdbl(input_reg, Operand::StaticVariable(nan));
2987 __ jmp(&done, Label::kNear); 2990 __ jmp(&done, Label::kNear);
2988 __ bind(&zero); 2991 __ bind(&zero);
2989 __ push(Immediate(0xFFF00000)); 2992 __ push(Immediate(0xFFF00000));
(...skipping 11 matching lines...) Expand all
3001 __ movdbl(input_reg, Operand(esp, 0)); 3004 __ movdbl(input_reg, Operand(esp, 0));
3002 __ add(Operand(esp), Immediate(kDoubleSize)); 3005 __ add(Operand(esp), Immediate(kDoubleSize));
3003 __ bind(&done); 3006 __ bind(&done);
3004 } 3007 }
3005 3008
3006 3009
3007 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { 3010 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
3008 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3011 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3009 TranscendentalCacheStub stub(TranscendentalCache::COS, 3012 TranscendentalCacheStub stub(TranscendentalCache::COS,
3010 TranscendentalCacheStub::UNTAGGED); 3013 TranscendentalCacheStub::UNTAGGED);
3011 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 3014 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3012 } 3015 }
3013 3016
3014 3017
3015 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { 3018 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
3016 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3019 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3017 TranscendentalCacheStub stub(TranscendentalCache::SIN, 3020 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3018 TranscendentalCacheStub::UNTAGGED); 3021 TranscendentalCacheStub::UNTAGGED);
3019 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 3022 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3020 } 3023 }
3021 3024
3022 3025
3023 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { 3026 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
3024 switch (instr->op()) { 3027 switch (instr->op()) {
3025 case kMathAbs: 3028 case kMathAbs:
3026 DoMathAbs(instr); 3029 DoMathAbs(instr);
3027 break; 3030 break;
3028 case kMathFloor: 3031 case kMathFloor:
3029 DoMathFloor(instr); 3032 DoMathFloor(instr);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3069 3072
3070 3073
3071 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 3074 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
3072 ASSERT(ToRegister(instr->context()).is(esi)); 3075 ASSERT(ToRegister(instr->context()).is(esi));
3073 ASSERT(ToRegister(instr->key()).is(ecx)); 3076 ASSERT(ToRegister(instr->key()).is(ecx));
3074 ASSERT(ToRegister(instr->result()).is(eax)); 3077 ASSERT(ToRegister(instr->result()).is(eax));
3075 3078
3076 int arity = instr->arity(); 3079 int arity = instr->arity();
3077 Handle<Code> ic = isolate()->stub_cache()-> 3080 Handle<Code> ic = isolate()->stub_cache()->
3078 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); 3081 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
3079 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 3082 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3080 } 3083 }
3081 3084
3082 3085
3083 void LCodeGen::DoCallNamed(LCallNamed* instr) { 3086 void LCodeGen::DoCallNamed(LCallNamed* instr) {
3084 ASSERT(ToRegister(instr->context()).is(esi)); 3087 ASSERT(ToRegister(instr->context()).is(esi));
3085 ASSERT(ToRegister(instr->result()).is(eax)); 3088 ASSERT(ToRegister(instr->result()).is(eax));
3086 3089
3087 int arity = instr->arity(); 3090 int arity = instr->arity();
3088 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3091 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3089 Handle<Code> ic = 3092 Handle<Code> ic =
3090 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); 3093 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
3091 __ mov(ecx, instr->name()); 3094 __ mov(ecx, instr->name());
3092 CallCode(ic, mode, instr, CONTEXT_ADJUSTED); 3095 CallCode(ic, mode, instr);
3093 } 3096 }
3094 3097
3095 3098
3096 void LCodeGen::DoCallFunction(LCallFunction* instr) { 3099 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3097 ASSERT(ToRegister(instr->context()).is(esi)); 3100 ASSERT(ToRegister(instr->context()).is(esi));
3098 ASSERT(ToRegister(instr->result()).is(eax)); 3101 ASSERT(ToRegister(instr->result()).is(eax));
3099 3102
3100 int arity = instr->arity(); 3103 int arity = instr->arity();
3101 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); 3104 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
3102 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 3105 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3103 __ Drop(1); 3106 __ Drop(1);
3104 } 3107 }
3105 3108
3106 3109
3107 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 3110 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
3108 ASSERT(ToRegister(instr->context()).is(esi)); 3111 ASSERT(ToRegister(instr->context()).is(esi));
3109 ASSERT(ToRegister(instr->result()).is(eax)); 3112 ASSERT(ToRegister(instr->result()).is(eax));
3110 3113
3111 int arity = instr->arity(); 3114 int arity = instr->arity();
3112 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 3115 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
3113 Handle<Code> ic = 3116 Handle<Code> ic =
3114 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); 3117 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
3115 __ mov(ecx, instr->name()); 3118 __ mov(ecx, instr->name());
3116 CallCode(ic, mode, instr, CONTEXT_ADJUSTED); 3119 CallCode(ic, mode, instr);
3117 } 3120 }
3118 3121
3119 3122
3120 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 3123 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
3121 ASSERT(ToRegister(instr->result()).is(eax)); 3124 ASSERT(ToRegister(instr->result()).is(eax));
3122 __ mov(edi, instr->target()); 3125 __ mov(edi, instr->target());
3123 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); 3126 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
3124 } 3127 }
3125 3128
3126 3129
3127 void LCodeGen::DoCallNew(LCallNew* instr) { 3130 void LCodeGen::DoCallNew(LCallNew* instr) {
3128 ASSERT(ToRegister(instr->context()).is(esi)); 3131 ASSERT(ToRegister(instr->context()).is(esi));
3129 ASSERT(ToRegister(instr->constructor()).is(edi)); 3132 ASSERT(ToRegister(instr->constructor()).is(edi));
3130 ASSERT(ToRegister(instr->result()).is(eax)); 3133 ASSERT(ToRegister(instr->result()).is(eax));
3131 3134
3132 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); 3135 Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
3133 __ Set(eax, Immediate(instr->arity())); 3136 __ Set(eax, Immediate(instr->arity()));
3134 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr, CONTEXT_ADJUSTED); 3137 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
3135 } 3138 }
3136 3139
3137 3140
3138 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3141 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3139 CallRuntime(instr->function(), instr->arity(), instr, RESTORE_CONTEXT); 3142 CallRuntime(instr->function(), instr->arity(), instr);
3140 } 3143 }
3141 3144
3142 3145
3143 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3146 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3144 Register object = ToRegister(instr->object()); 3147 Register object = ToRegister(instr->object());
3145 Register value = ToRegister(instr->value()); 3148 Register value = ToRegister(instr->value());
3146 int offset = instr->offset(); 3149 int offset = instr->offset();
3147 3150
3148 if (!instr->transition().is_null()) { 3151 if (!instr->transition().is_null()) {
3149 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 3152 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
(...skipping 22 matching lines...) Expand all
3172 3175
3173 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 3176 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
3174 ASSERT(ToRegister(instr->context()).is(esi)); 3177 ASSERT(ToRegister(instr->context()).is(esi));
3175 ASSERT(ToRegister(instr->object()).is(edx)); 3178 ASSERT(ToRegister(instr->object()).is(edx));
3176 ASSERT(ToRegister(instr->value()).is(eax)); 3179 ASSERT(ToRegister(instr->value()).is(eax));
3177 3180
3178 __ mov(ecx, instr->name()); 3181 __ mov(ecx, instr->name());
3179 Handle<Code> ic = instr->strict_mode() 3182 Handle<Code> ic = instr->strict_mode()
3180 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3183 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3181 : isolate()->builtins()->StoreIC_Initialize(); 3184 : isolate()->builtins()->StoreIC_Initialize();
3182 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 3185 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3183 } 3186 }
3184 3187
3185 3188
3186 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 3189 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
3187 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 3190 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
3188 DeoptimizeIf(above_equal, instr->environment()); 3191 DeoptimizeIf(above_equal, instr->environment());
3189 } 3192 }
3190 3193
3191 3194
3192 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3195 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3262 3265
3263 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3266 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3264 ASSERT(ToRegister(instr->context()).is(esi)); 3267 ASSERT(ToRegister(instr->context()).is(esi));
3265 ASSERT(ToRegister(instr->object()).is(edx)); 3268 ASSERT(ToRegister(instr->object()).is(edx));
3266 ASSERT(ToRegister(instr->key()).is(ecx)); 3269 ASSERT(ToRegister(instr->key()).is(ecx));
3267 ASSERT(ToRegister(instr->value()).is(eax)); 3270 ASSERT(ToRegister(instr->value()).is(eax));
3268 3271
3269 Handle<Code> ic = instr->strict_mode() 3272 Handle<Code> ic = instr->strict_mode()
3270 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3273 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3271 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3274 : isolate()->builtins()->KeyedStoreIC_Initialize();
3272 CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); 3275 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3273 } 3276 }
3274 3277
3275 3278
3276 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 3279 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
3277 class DeferredStringCharCodeAt: public LDeferredCode { 3280 class DeferredStringCharCodeAt: public LDeferredCode {
3278 public: 3281 public:
3279 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 3282 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
3280 : LDeferredCode(codegen), instr_(instr) { } 3283 : LDeferredCode(codegen), instr_(instr) { }
3281 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 3284 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
3282 private: 3285 private:
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 // DoStringCharCodeAt above. 3396 // DoStringCharCodeAt above.
3394 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 3397 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3395 if (instr->index()->IsConstantOperand()) { 3398 if (instr->index()->IsConstantOperand()) {
3396 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3399 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3397 __ push(Immediate(Smi::FromInt(const_index))); 3400 __ push(Immediate(Smi::FromInt(const_index)));
3398 } else { 3401 } else {
3399 Register index = ToRegister(instr->index()); 3402 Register index = ToRegister(instr->index());
3400 __ SmiTag(index); 3403 __ SmiTag(index);
3401 __ push(index); 3404 __ push(index);
3402 } 3405 }
3403 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); 3406 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2,
3407 instr, instr->context());
3404 if (FLAG_debug_code) { 3408 if (FLAG_debug_code) {
3405 __ AbortIfNotSmi(eax); 3409 __ AbortIfNotSmi(eax);
3406 } 3410 }
3407 __ SmiUntag(eax); 3411 __ SmiUntag(eax);
3408 __ StoreToSafepointRegisterSlot(result, eax); 3412 __ StoreToSafepointRegisterSlot(result, eax);
3409 } 3413 }
3410 3414
3411 3415
3412 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 3416 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
3413 class DeferredStringCharFromCode: public LDeferredCode { 3417 class DeferredStringCharFromCode: public LDeferredCode {
(...skipping 30 matching lines...) Expand all
3444 Register result = ToRegister(instr->result()); 3448 Register result = ToRegister(instr->result());
3445 3449
3446 // TODO(3095996): Get rid of this. For now, we need to make the 3450 // TODO(3095996): Get rid of this. For now, we need to make the
3447 // result register contain a valid pointer because it is already 3451 // result register contain a valid pointer because it is already
3448 // contained in the register pointer map. 3452 // contained in the register pointer map.
3449 __ Set(result, Immediate(0)); 3453 __ Set(result, Immediate(0));
3450 3454
3451 PushSafepointRegistersScope scope(this); 3455 PushSafepointRegistersScope scope(this);
3452 __ SmiTag(char_code); 3456 __ SmiTag(char_code);
3453 __ push(char_code); 3457 __ push(char_code);
3454 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 3458 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
3455 __ StoreToSafepointRegisterSlot(result, eax); 3459 __ StoreToSafepointRegisterSlot(result, eax);
3456 } 3460 }
3457 3461
3458 3462
3459 void LCodeGen::DoStringLength(LStringLength* instr) { 3463 void LCodeGen::DoStringLength(LStringLength* instr) {
3460 Register string = ToRegister(instr->string()); 3464 Register string = ToRegister(instr->string());
3461 Register result = ToRegister(instr->result()); 3465 Register result = ToRegister(instr->result());
3462 __ mov(result, FieldOperand(string, String::kLengthOffset)); 3466 __ mov(result, FieldOperand(string, String::kLengthOffset));
3463 } 3467 }
3464 3468
3465 3469
3466 void LCodeGen::DoStringAdd(LStringAdd* instr) { 3470 void LCodeGen::DoStringAdd(LStringAdd* instr) {
3467 if (instr->left()->IsConstantOperand()) { 3471 if (instr->left()->IsConstantOperand()) {
3468 __ push(ToImmediate(instr->left())); 3472 __ push(ToImmediate(instr->left()));
3469 } else { 3473 } else {
3470 __ push(ToOperand(instr->left())); 3474 __ push(ToOperand(instr->left()));
3471 } 3475 }
3472 if (instr->right()->IsConstantOperand()) { 3476 if (instr->right()->IsConstantOperand()) {
3473 __ push(ToImmediate(instr->right())); 3477 __ push(ToImmediate(instr->right()));
3474 } else { 3478 } else {
3475 __ push(ToOperand(instr->right())); 3479 __ push(ToOperand(instr->right()));
3476 } 3480 }
3477 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 3481 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
3478 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 3482 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3479 } 3483 }
3480 3484
3481 3485
3482 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 3486 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
3483 LOperand* input = instr->InputAt(0); 3487 LOperand* input = instr->InputAt(0);
3484 ASSERT(input->IsRegister() || input->IsStackSlot()); 3488 ASSERT(input->IsRegister() || input->IsStackSlot());
3485 LOperand* output = instr->result(); 3489 LOperand* output = instr->result();
3486 ASSERT(output->IsDoubleRegister()); 3490 ASSERT(output->IsDoubleRegister());
3487 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 3491 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
3488 } 3492 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3529 __ jmp(&done, Label::kNear); 3533 __ jmp(&done, Label::kNear);
3530 } 3534 }
3531 3535
3532 // Slow case: Call the runtime system to do the number allocation. 3536 // Slow case: Call the runtime system to do the number allocation.
3533 __ bind(&slow); 3537 __ bind(&slow);
3534 3538
3535 // TODO(3095996): Put a valid pointer value in the stack slot where the result 3539 // TODO(3095996): Put a valid pointer value in the stack slot where the result
3536 // register is stored, as this register is in the pointer map, but contains an 3540 // register is stored, as this register is in the pointer map, but contains an
3537 // integer value. 3541 // integer value.
3538 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); 3542 __ StoreToSafepointRegisterSlot(reg, Immediate(0));
3539 3543 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
Kevin Millikin (Chromium) 2011/06/29 08:36:20 This needs a comment that we're potentially passin
William Hesse 2011/06/29 10:30:21 Done.
3540 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 3544 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
3545 RecordSafepointWithRegisters(
3546 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
3541 if (!reg.is(eax)) __ mov(reg, eax); 3547 if (!reg.is(eax)) __ mov(reg, eax);
3542 3548
3543 // Done. Put the value in xmm0 into the value of the allocated heap 3549 // Done. Put the value in xmm0 into the value of the allocated heap
3544 // number. 3550 // number.
3545 __ bind(&done); 3551 __ bind(&done);
3546 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 3552 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
3547 __ StoreToSafepointRegisterSlot(reg, reg); 3553 __ StoreToSafepointRegisterSlot(reg, reg);
3548 } 3554 }
3549 3555
3550 3556
(...skipping 23 matching lines...) Expand all
3574 3580
3575 3581
3576 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 3582 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
3577 // TODO(3095996): Get rid of this. For now, we need to make the 3583 // TODO(3095996): Get rid of this. For now, we need to make the
3578 // result register contain a valid pointer because it is already 3584 // result register contain a valid pointer because it is already
3579 // contained in the register pointer map. 3585 // contained in the register pointer map.
3580 Register reg = ToRegister(instr->result()); 3586 Register reg = ToRegister(instr->result());
3581 __ Set(reg, Immediate(0)); 3587 __ Set(reg, Immediate(0));
3582 3588
3583 PushSafepointRegistersScope scope(this); 3589 PushSafepointRegistersScope scope(this);
3584 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 3590 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3591 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
3592 RecordSafepointWithRegisters(instr->pointer_map(), 0,
3593 » » » Safepoint::kNoDeoptimizationIndex);
3585 __ StoreToSafepointRegisterSlot(reg, eax); 3594 __ StoreToSafepointRegisterSlot(reg, eax);
3586 } 3595 }
3587 3596
3588 3597
3589 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3598 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3590 LOperand* input = instr->InputAt(0); 3599 LOperand* input = instr->InputAt(0);
3591 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3600 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3592 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 3601 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
3593 __ SmiTag(ToRegister(input)); 3602 __ SmiTag(ToRegister(input));
3594 } 3603 }
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
4044 } 4053 }
4045 4054
4046 // Check the holder map. 4055 // Check the holder map.
4047 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4056 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
4048 Handle<Map>(current_prototype->map())); 4057 Handle<Map>(current_prototype->map()));
4049 DeoptimizeIf(not_equal, instr->environment()); 4058 DeoptimizeIf(not_equal, instr->environment());
4050 } 4059 }
4051 4060
4052 4061
4053 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4062 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4063 ASSERT(ToRegister(instr->context()).is(esi));
4054 // Setup the parameters to the stub/runtime call. 4064 // Setup the parameters to the stub/runtime call.
4055 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4065 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4056 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); 4066 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
4057 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 4067 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
4058 __ push(Immediate(instr->hydrogen()->constant_elements())); 4068 __ push(Immediate(instr->hydrogen()->constant_elements()));
4059 4069
4060 // Pick the right runtime function or stub to call. 4070 // Pick the right runtime function or stub to call.
4061 int length = instr->hydrogen()->length(); 4071 int length = instr->hydrogen()->length();
4062 if (instr->hydrogen()->IsCopyOnWrite()) { 4072 if (instr->hydrogen()->IsCopyOnWrite()) {
4063 ASSERT(instr->hydrogen()->depth() == 1); 4073 ASSERT(instr->hydrogen()->depth() == 1);
4064 FastCloneShallowArrayStub::Mode mode = 4074 FastCloneShallowArrayStub::Mode mode =
4065 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; 4075 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
4066 FastCloneShallowArrayStub stub(mode, length); 4076 FastCloneShallowArrayStub stub(mode, length);
4067 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 4077 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4068 } else if (instr->hydrogen()->depth() > 1) { 4078 } else if (instr->hydrogen()->depth() > 1) {
4069 CallRuntime(Runtime::kCreateArrayLiteral, 3, instr, RESTORE_CONTEXT); 4079 CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
4070 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { 4080 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
4071 CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr, RESTORE_CONTEXT); 4081 CallRuntime(Runtime::kCreateArrayLiteralShallow, 3,
4082 instr);
4072 } else { 4083 } else {
4073 FastCloneShallowArrayStub::Mode mode = 4084 FastCloneShallowArrayStub::Mode mode =
4074 FastCloneShallowArrayStub::CLONE_ELEMENTS; 4085 FastCloneShallowArrayStub::CLONE_ELEMENTS;
4075 FastCloneShallowArrayStub stub(mode, length); 4086 FastCloneShallowArrayStub stub(mode, length);
4076 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 4087 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4077 } 4088 }
4078 } 4089 }
4079 4090
4080 4091
4081 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { 4092 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
4082 ASSERT(ToRegister(instr->context()).is(esi)); 4093 ASSERT(ToRegister(instr->context()).is(esi));
4083 // Setup the parameters to the stub/runtime call. 4094 // Setup the parameters to the stub/runtime call.
4084 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4095 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4085 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); 4096 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
4086 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 4097 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
4087 __ push(Immediate(instr->hydrogen()->constant_properties())); 4098 __ push(Immediate(instr->hydrogen()->constant_properties()));
4088 int flags = instr->hydrogen()->fast_elements() 4099 int flags = instr->hydrogen()->fast_elements()
4089 ? ObjectLiteral::kFastElements 4100 ? ObjectLiteral::kFastElements
4090 : ObjectLiteral::kNoFlags; 4101 : ObjectLiteral::kNoFlags;
4091 flags |= instr->hydrogen()->has_function() 4102 flags |= instr->hydrogen()->has_function()
4092 ? ObjectLiteral::kHasFunction 4103 ? ObjectLiteral::kHasFunction
4093 : ObjectLiteral::kNoFlags; 4104 : ObjectLiteral::kNoFlags;
4094 __ push(Immediate(Smi::FromInt(flags))); 4105 __ push(Immediate(Smi::FromInt(flags)));
4095 4106
4096 // Pick the right runtime function to call. 4107 // Pick the right runtime function to call.
4097 if (instr->hydrogen()->depth() > 1) { 4108 if (instr->hydrogen()->depth() > 1) {
4098 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr, CONTEXT_ADJUSTED); 4109 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr);
4099 } else { 4110 } else {
4100 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4111 CallRuntime(Runtime::kCreateObjectLiteralShallow,
4101 4, 4112 4,
4102 instr, 4113 instr);
4103 CONTEXT_ADJUSTED);
4104 } 4114 }
4105 } 4115 }
4106 4116
4107 4117
4108 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { 4118 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
4109 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 4119 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
4110 __ push(eax); 4120 __ push(eax);
4111 CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED); 4121 CallRuntime(Runtime::kToFastProperties, 1, instr);
4112 } 4122 }
4113 4123
4114 4124
4115 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 4125 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
4126 ASSERT(ToRegister(instr->context()).is(esi));
4116 Label materialized; 4127 Label materialized;
4117 // Registers will be used as follows: 4128 // Registers will be used as follows:
4118 // edi = JS function. 4129 // edi = JS function.
4119 // ecx = literals array. 4130 // ecx = literals array.
4120 // ebx = regexp literal. 4131 // ebx = regexp literal.
4121 // eax = regexp literal clone. 4132 // eax = regexp literal clone.
4133 // esi = context.
4122 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4134 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4123 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 4135 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
4124 int literal_offset = FixedArray::kHeaderSize + 4136 int literal_offset = FixedArray::kHeaderSize +
4125 instr->hydrogen()->literal_index() * kPointerSize; 4137 instr->hydrogen()->literal_index() * kPointerSize;
4126 __ mov(ebx, FieldOperand(ecx, literal_offset)); 4138 __ mov(ebx, FieldOperand(ecx, literal_offset));
4127 __ cmp(ebx, factory()->undefined_value()); 4139 __ cmp(ebx, factory()->undefined_value());
4128 __ j(not_equal, &materialized, Label::kNear); 4140 __ j(not_equal, &materialized, Label::kNear);
4129 4141
4130 // Create regexp literal using runtime function 4142 // Create regexp literal using runtime function
4131 // Result will be in eax. 4143 // Result will be in eax.
4132 __ push(ecx); 4144 __ push(ecx);
4133 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 4145 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
4134 __ push(Immediate(instr->hydrogen()->pattern())); 4146 __ push(Immediate(instr->hydrogen()->pattern()));
4135 __ push(Immediate(instr->hydrogen()->flags())); 4147 __ push(Immediate(instr->hydrogen()->flags()));
4136 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT); 4148 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
4137 __ mov(ebx, eax); 4149 __ mov(ebx, eax);
4138 4150
4139 __ bind(&materialized); 4151 __ bind(&materialized);
4140 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 4152 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
4141 Label allocated, runtime_allocate; 4153 Label allocated, runtime_allocate;
4142 __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); 4154 __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
4143 __ jmp(&allocated); 4155 __ jmp(&allocated);
4144 4156
4145 __ bind(&runtime_allocate); 4157 __ bind(&runtime_allocate);
4146 __ push(ebx); 4158 __ push(ebx);
4147 __ push(Immediate(Smi::FromInt(size))); 4159 __ push(Immediate(Smi::FromInt(size)));
4148 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr, RESTORE_CONTEXT); 4160 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
4149 __ pop(ebx); 4161 __ pop(ebx);
4150 4162
4151 __ bind(&allocated); 4163 __ bind(&allocated);
4152 // Copy the content into the newly allocated memory. 4164 // Copy the content into the newly allocated memory.
4153 // (Unroll copy loop once for better throughput). 4165 // (Unroll copy loop once for better throughput).
4154 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 4166 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) {
4155 __ mov(edx, FieldOperand(ebx, i)); 4167 __ mov(edx, FieldOperand(ebx, i));
4156 __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); 4168 __ mov(ecx, FieldOperand(ebx, i + kPointerSize));
4157 __ mov(FieldOperand(eax, i), edx); 4169 __ mov(FieldOperand(eax, i), edx);
4158 __ mov(FieldOperand(eax, i + kPointerSize), ecx); 4170 __ mov(FieldOperand(eax, i + kPointerSize), ecx);
4159 } 4171 }
4160 if ((size % (2 * kPointerSize)) != 0) { 4172 if ((size % (2 * kPointerSize)) != 0) {
4161 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); 4173 __ mov(edx, FieldOperand(ebx, size - kPointerSize));
4162 __ mov(FieldOperand(eax, size - kPointerSize), edx); 4174 __ mov(FieldOperand(eax, size - kPointerSize), edx);
4163 } 4175 }
4164 } 4176 }
4165 4177
4166 4178
4167 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 4179 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
4180 ASSERT(ToRegister(instr->context()).is(esi));
4168 // Use the fast case closure allocation code that allocates in new 4181 // Use the fast case closure allocation code that allocates in new
4169 // space for nested functions that don't need literals cloning. 4182 // space for nested functions that don't need literals cloning.
4170 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); 4183 Handle<SharedFunctionInfo> shared_info = instr->shared_info();
4171 bool pretenure = instr->hydrogen()->pretenure(); 4184 bool pretenure = instr->hydrogen()->pretenure();
4172 if (!pretenure && shared_info->num_literals() == 0) { 4185 if (!pretenure && shared_info->num_literals() == 0) {
4173 FastNewClosureStub stub( 4186 FastNewClosureStub stub(
4174 shared_info->strict_mode() ? kStrictMode : kNonStrictMode); 4187 shared_info->strict_mode() ? kStrictMode : kNonStrictMode);
4175 __ push(Immediate(shared_info)); 4188 __ push(Immediate(shared_info));
4176 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 4189 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4177 } else { 4190 } else {
4178 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); 4191 __ push(Operand(ebp, StandardFrameConstants::kContextOffset));
4179 __ push(Immediate(shared_info)); 4192 __ push(Immediate(shared_info));
4180 __ push(Immediate(pretenure 4193 __ push(Immediate(pretenure
4181 ? factory()->true_value() 4194 ? factory()->true_value()
4182 : factory()->false_value())); 4195 : factory()->false_value()));
4183 CallRuntime(Runtime::kNewClosure, 3, instr, RESTORE_CONTEXT); 4196 CallRuntime(Runtime::kNewClosure, 3, instr);
4184 } 4197 }
4185 } 4198 }
4186 4199
4187 4200
4188 void LCodeGen::DoTypeof(LTypeof* instr) { 4201 void LCodeGen::DoTypeof(LTypeof* instr) {
4189 LOperand* input = instr->InputAt(0); 4202 LOperand* input = instr->InputAt(1);
4190 if (input->IsConstantOperand()) { 4203 if (input->IsConstantOperand()) {
4191 __ push(ToImmediate(input)); 4204 __ push(ToImmediate(input));
4192 } else { 4205 } else {
4193 __ push(ToOperand(input)); 4206 __ push(ToOperand(input));
4194 } 4207 }
4195 CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); 4208 CallRuntime(Runtime::kTypeof, 1, instr);
4196 } 4209 }
4197 4210
4198 4211
4199 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { 4212 void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
4200 Register input = ToRegister(instr->InputAt(0)); 4213 Register input = ToRegister(instr->InputAt(0));
4201 Register result = ToRegister(instr->result()); 4214 Register result = ToRegister(instr->result());
4202 Label true_label; 4215 Label true_label;
4203 Label false_label; 4216 Label false_label;
4204 Label done; 4217 Label done;
4205 4218
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 LPointerMap* pointers = instr->pointer_map(); 4382 LPointerMap* pointers = instr->pointer_map();
4370 LEnvironment* env = instr->deoptimization_environment(); 4383 LEnvironment* env = instr->deoptimization_environment();
4371 RecordPosition(pointers->position()); 4384 RecordPosition(pointers->position());
4372 RegisterEnvironmentForDeoptimization(env); 4385 RegisterEnvironmentForDeoptimization(env);
4373 // Create safepoint generator that will also ensure enough space in the 4386 // Create safepoint generator that will also ensure enough space in the
4374 // reloc info for patching in deoptimization (since this is invoking a 4387 // reloc info for patching in deoptimization (since this is invoking a
4375 // builtin) 4388 // builtin)
4376 SafepointGenerator safepoint_generator(this, 4389 SafepointGenerator safepoint_generator(this,
4377 pointers, 4390 pointers,
4378 env->deoptimization_index()); 4391 env->deoptimization_index());
4379 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4380 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 4392 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
4381 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); 4393 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
4382 } 4394 }
4383 4395
4384 4396
4385 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 4397 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
4386 PushSafepointRegistersScope scope(this); 4398 PushSafepointRegistersScope scope(this);
4387 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr); 4399 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr, instr->context());
4388 } 4400 }
4389 4401
4390 4402
4391 void LCodeGen::DoStackCheck(LStackCheck* instr) { 4403 void LCodeGen::DoStackCheck(LStackCheck* instr) {
4392 class DeferredStackCheck: public LDeferredCode { 4404 class DeferredStackCheck: public LDeferredCode {
4393 public: 4405 public:
4394 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 4406 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
4395 : LDeferredCode(codegen), instr_(instr) { } 4407 : LDeferredCode(codegen), instr_(instr) { }
4396 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 4408 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
4397 private: 4409 private:
4398 LStackCheck* instr_; 4410 LStackCheck* instr_;
4399 }; 4411 };
4400 4412
4413 // TODO(whesse): Fix with context.
4401 if (instr->hydrogen()->is_function_entry()) { 4414 if (instr->hydrogen()->is_function_entry()) {
4402 // Perform stack overflow check. 4415 // Perform stack overflow check.
4403 Label done; 4416 Label done;
4404 ExternalReference stack_limit = 4417 ExternalReference stack_limit =
4405 ExternalReference::address_of_stack_limit(isolate()); 4418 ExternalReference::address_of_stack_limit(isolate());
4406 __ cmp(esp, Operand::StaticVariable(stack_limit)); 4419 __ cmp(esp, Operand::StaticVariable(stack_limit));
4407 __ j(above_equal, &done, Label::kNear); 4420 __ j(above_equal, &done, Label::kNear);
4408 4421
4422 ASSERT(instr->context()->IsRegister());
4423 ASSERT(ToRegister(instr->context()).is(esi));
4409 StackCheckStub stub; 4424 StackCheckStub stub;
4410 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); 4425 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4411 __ bind(&done); 4426 __ bind(&done);
4412 } else { 4427 } else {
4413 ASSERT(instr->hydrogen()->is_backwards_branch()); 4428 ASSERT(instr->hydrogen()->is_backwards_branch());
4414 // Perform stack overflow check if this goto needs it before jumping. 4429 // Perform stack overflow check if this goto needs it before jumping.
4415 DeferredStackCheck* deferred_stack_check = 4430 DeferredStackCheck* deferred_stack_check =
4416 new DeferredStackCheck(this, instr); 4431 new DeferredStackCheck(this, instr);
4417 ExternalReference stack_limit = 4432 ExternalReference stack_limit =
4418 ExternalReference::address_of_stack_limit(isolate()); 4433 ExternalReference::address_of_stack_limit(isolate());
4419 __ cmp(esp, Operand::StaticVariable(stack_limit)); 4434 __ cmp(esp, Operand::StaticVariable(stack_limit));
4420 __ j(below, deferred_stack_check->entry()); 4435 __ j(below, deferred_stack_check->entry());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4458 LPointerMap* pointers = instr->pointer_map(); 4473 LPointerMap* pointers = instr->pointer_map();
4459 LEnvironment* env = instr->deoptimization_environment(); 4474 LEnvironment* env = instr->deoptimization_environment();
4460 RecordPosition(pointers->position()); 4475 RecordPosition(pointers->position());
4461 RegisterEnvironmentForDeoptimization(env); 4476 RegisterEnvironmentForDeoptimization(env);
4462 // Create safepoint generator that will also ensure enough space in the 4477 // Create safepoint generator that will also ensure enough space in the
4463 // reloc info for patching in deoptimization (since this is invoking a 4478 // reloc info for patching in deoptimization (since this is invoking a
4464 // builtin) 4479 // builtin)
4465 SafepointGenerator safepoint_generator(this, 4480 SafepointGenerator safepoint_generator(this,
4466 pointers, 4481 pointers,
4467 env->deoptimization_index()); 4482 env->deoptimization_index());
4483 // TODO(whesse): FIX.
4468 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4484 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4469 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4485 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4470 } 4486 }
4471 4487
4472 4488
4473 #undef __ 4489 #undef __
4474 4490
4475 } } // namespace v8::internal 4491 } } // namespace v8::internal
4476 4492
4477 #endif // V8_TARGET_ARCH_IA32 4493 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698