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

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

Issue 145773008: A64: Synchronize with r17104. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 info()->CommitDependencies(code); 113 info()->CommitDependencies(code);
114 } 114 }
115 115
116 116
117 void LCodeGen::Abort(BailoutReason reason) { 117 void LCodeGen::Abort(BailoutReason reason) {
118 info()->set_bailout_reason(reason); 118 info()->set_bailout_reason(reason);
119 status_ = ABORTED; 119 status_ = ABORTED;
120 } 120 }
121 121
122 122
123 void LCodeGen::Comment(const char* format, ...) {
124 if (!FLAG_code_comments) return;
125 char buffer[4 * KB];
126 StringBuilder builder(buffer, ARRAY_SIZE(buffer));
127 va_list arguments;
128 va_start(arguments, format);
129 builder.AddFormattedList(format, arguments);
130 va_end(arguments);
131
132 // Copy the string before recording it in the assembler to avoid
133 // issues when the stack allocated buffer goes out of scope.
134 size_t length = builder.position();
135 Vector<char> copy = Vector<char>::New(length + 1);
136 OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
137 masm()->RecordComment(copy.start());
138 }
139
140
141 #ifdef _MSC_VER 123 #ifdef _MSC_VER
142 void LCodeGen::MakeSureStackPagesMapped(int offset) { 124 void LCodeGen::MakeSureStackPagesMapped(int offset) {
143 const int kPageSize = 4 * KB; 125 const int kPageSize = 4 * KB;
144 for (offset -= kPageSize; offset > 0; offset -= kPageSize) { 126 for (offset -= kPageSize; offset > 0; offset -= kPageSize) {
145 __ mov(Operand(esp, offset), eax); 127 __ mov(Operand(esp, offset), eax);
146 } 128 }
147 } 129 }
148 #endif 130 #endif
149 131
150 132
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 __ mov(alignment_loc, edx); 359 __ mov(alignment_loc, edx);
378 360
379 // Adjust the frame size, subsuming the unoptimized frame into the 361 // Adjust the frame size, subsuming the unoptimized frame into the
380 // optimized frame. 362 // optimized frame.
381 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 363 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
382 ASSERT(slots >= 1); 364 ASSERT(slots >= 1);
383 __ sub(esp, Immediate((slots - 1) * kPointerSize)); 365 __ sub(esp, Immediate((slots - 1) * kPointerSize));
384 } 366 }
385 367
386 368
387 bool LCodeGen::GenerateBody() { 369 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
388 ASSERT(is_generating()); 370 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
389 bool emit_instructions = true;
390 for (current_instruction_ = 0;
391 !is_aborted() && current_instruction_ < instructions_->length();
392 current_instruction_++) {
393 LInstruction* instr = instructions_->at(current_instruction_);
394
395 // Don't emit code for basic blocks with a replacement.
396 if (instr->IsLabel()) {
397 emit_instructions = !LLabel::cast(instr)->HasReplacement();
398 }
399 if (!emit_instructions) continue;
400
401 if (FLAG_code_comments && instr->HasInterestingComment(this)) {
402 Comment(";;; <@%d,#%d> %s",
403 current_instruction_,
404 instr->hydrogen_value()->id(),
405 instr->Mnemonic());
406 }
407
408 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
409
410 RecordAndUpdatePosition(instr->position());
411
412 instr->CompileToNative(this);
413
414 if (!CpuFeatures::IsSupported(SSE2)) {
415 if (instr->IsGoto()) {
416 x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr));
417 } else if (FLAG_debug_code && FLAG_enable_slow_asserts &&
418 !instr->IsGap() && !instr->IsReturn()) {
419 if (instr->ClobbersDoubleRegisters()) {
420 if (instr->HasDoubleRegisterResult()) {
421 ASSERT_EQ(1, x87_stack_.depth());
422 } else {
423 ASSERT_EQ(0, x87_stack_.depth());
424 }
425 }
426 __ VerifyX87StackDepth(x87_stack_.depth());
427 }
428 }
429 }
430 EnsureSpaceForLazyDeopt();
431 return !is_aborted();
432 } 371 }
433 372
434 373
374 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
375 if (!CpuFeatures::IsSupported(SSE2)) {
376 if (instr->IsGoto()) {
377 x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr));
378 } else if (FLAG_debug_code && FLAG_enable_slow_asserts &&
379 !instr->IsGap() && !instr->IsReturn()) {
380 if (instr->ClobbersDoubleRegisters()) {
381 if (instr->HasDoubleRegisterResult()) {
382 ASSERT_EQ(1, x87_stack_.depth());
383 } else {
384 ASSERT_EQ(0, x87_stack_.depth());
385 }
386 }
387 __ VerifyX87StackDepth(x87_stack_.depth());
388 }
389 }
390 }
391
392
435 bool LCodeGen::GenerateJumpTable() { 393 bool LCodeGen::GenerateJumpTable() {
436 Label needs_frame; 394 Label needs_frame;
437 if (jump_table_.length() > 0) { 395 if (jump_table_.length() > 0) {
438 Comment(";;; -------------------- Jump table --------------------"); 396 Comment(";;; -------------------- Jump table --------------------");
439 } 397 }
440 for (int i = 0; i < jump_table_.length(); i++) { 398 for (int i = 0; i < jump_table_.length(); i++) {
441 __ bind(&jump_table_[i].label); 399 __ bind(&jump_table_[i].label);
442 Address entry = jump_table_[i].address; 400 Address entry = jump_table_[i].address;
443 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; 401 Deoptimizer::BailoutType type = jump_table_[i].bailout_type;
444 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 402 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 951
994 void LCodeGen::CallCode(Handle<Code> code, 952 void LCodeGen::CallCode(Handle<Code> code,
995 RelocInfo::Mode mode, 953 RelocInfo::Mode mode,
996 LInstruction* instr) { 954 LInstruction* instr) {
997 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 955 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
998 } 956 }
999 957
1000 958
1001 void LCodeGen::CallRuntime(const Runtime::Function* fun, 959 void LCodeGen::CallRuntime(const Runtime::Function* fun,
1002 int argc, 960 int argc,
1003 LInstruction* instr) { 961 LInstruction* instr,
962 SaveFPRegsMode save_doubles) {
1004 ASSERT(instr != NULL); 963 ASSERT(instr != NULL);
1005 ASSERT(instr->HasPointerMap()); 964 ASSERT(instr->HasPointerMap());
1006 LPointerMap* pointers = instr->pointer_map(); 965 LPointerMap* pointers = instr->pointer_map();
1007 RecordPosition(pointers->position()); 966 RecordPosition(pointers->position());
1008 967
1009 __ CallRuntime(fun, argc); 968 __ CallRuntime(fun, argc, save_doubles);
1010 969
1011 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 970 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
1012 971
1013 ASSERT(info()->is_calling()); 972 ASSERT(info()->is_calling());
1014 } 973 }
1015 974
1016 975
1017 void LCodeGen::LoadContextFromDeferred(LOperand* context) { 976 void LCodeGen::LoadContextFromDeferred(LOperand* context) {
1018 if (context->IsRegister()) { 977 if (context->IsRegister()) {
1019 if (!ToRegister(context).is(esi)) { 978 if (!ToRegister(context).is(esi)) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 LEnvironment* environment) { 1120 LEnvironment* environment) {
1162 Deoptimizer::BailoutType bailout_type = info()->IsStub() 1121 Deoptimizer::BailoutType bailout_type = info()->IsStub()
1163 ? Deoptimizer::LAZY 1122 ? Deoptimizer::LAZY
1164 : Deoptimizer::EAGER; 1123 : Deoptimizer::EAGER;
1165 DeoptimizeIf(cc, environment, bailout_type); 1124 DeoptimizeIf(cc, environment, bailout_type);
1166 } 1125 }
1167 1126
1168 1127
1169 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 1128 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
1170 ZoneList<Handle<Map> > maps(1, zone()); 1129 ZoneList<Handle<Map> > maps(1, zone());
1130 ZoneList<Handle<JSObject> > objects(1, zone());
1171 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 1131 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1172 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 1132 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
1173 RelocInfo::Mode mode = it.rinfo()->rmode(); 1133 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) {
1174 if (mode == RelocInfo::EMBEDDED_OBJECT && 1134 if (it.rinfo()->target_object()->IsMap()) {
1175 it.rinfo()->target_object()->IsMap()) { 1135 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
1176 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
1177 if (map->CanTransition()) {
1178 maps.Add(map, zone()); 1136 maps.Add(map, zone());
1137 } else if (it.rinfo()->target_object()->IsJSObject()) {
1138 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
1139 objects.Add(object, zone());
1179 } 1140 }
1180 } 1141 }
1181 } 1142 }
1182 #ifdef VERIFY_HEAP 1143 #ifdef VERIFY_HEAP
1183 // This disables verification of weak embedded maps after full GC. 1144 // This disables verification of weak embedded objects after full GC.
1184 // AddDependentCode can cause a GC, which would observe the state where 1145 // AddDependentCode can cause a GC, which would observe the state where
1185 // this code is not yet in the depended code lists of the embedded maps. 1146 // this code is not yet in the depended code lists of the embedded maps.
1186 NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps; 1147 NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
1187 #endif 1148 #endif
1188 for (int i = 0; i < maps.length(); i++) { 1149 for (int i = 0; i < maps.length(); i++) {
1189 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); 1150 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
1190 } 1151 }
1152 for (int i = 0; i < objects.length(); i++) {
1153 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code);
1154 }
1191 } 1155 }
1192 1156
1193 1157
1194 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 1158 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
1195 int length = deoptimizations_.length(); 1159 int length = deoptimizations_.length();
1196 if (length == 0) return; 1160 if (length == 0) return;
1197 Handle<DeoptimizationInputData> data = 1161 Handle<DeoptimizationInputData> data =
1198 factory()->NewDeoptimizationInputData(length, TENURED); 1162 factory()->NewDeoptimizationInputData(length, TENURED);
1199 1163
1200 Handle<ByteArray> translations = 1164 Handle<ByteArray> translations =
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 __ fmul_i(1); 2269 __ fmul_i(1);
2306 break; 2270 break;
2307 case Token::DIV: 2271 case Token::DIV:
2308 __ fdiv_i(1); 2272 __ fdiv_i(1);
2309 break; 2273 break;
2310 case Token::MOD: { 2274 case Token::MOD: {
2311 // Pass two doubles as arguments on the stack. 2275 // Pass two doubles as arguments on the stack.
2312 __ PrepareCallCFunction(4, eax); 2276 __ PrepareCallCFunction(4, eax);
2313 X87Mov(Operand(esp, 1 * kDoubleSize), right); 2277 X87Mov(Operand(esp, 1 * kDoubleSize), right);
2314 X87Mov(Operand(esp, 0), left); 2278 X87Mov(Operand(esp, 0), left);
2279 X87Free(right);
2280 ASSERT(left.is(result));
2315 X87PrepareToWrite(result); 2281 X87PrepareToWrite(result);
2316 __ CallCFunction( 2282 __ CallCFunction(
2317 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2283 ExternalReference::double_fp_operation(Token::MOD, isolate()),
2318 4); 2284 4);
2319 2285
2320 // Return value is in st(0) on ia32. 2286 // Return value is in st(0) on ia32.
2321 X87CommitWrite(result); 2287 X87CommitWrite(result);
2322 break; 2288 break;
2323 } 2289 }
2324 default: 2290 default:
2325 UNREACHABLE(); 2291 UNREACHABLE();
2326 break; 2292 break;
2327 } 2293 }
2328 } 2294 }
2329 } 2295 }
2330 2296
2331 2297
2332 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2298 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2333 ASSERT(ToRegister(instr->context()).is(esi)); 2299 ASSERT(ToRegister(instr->context()).is(esi));
2334 ASSERT(ToRegister(instr->left()).is(edx)); 2300 ASSERT(ToRegister(instr->left()).is(edx));
2335 ASSERT(ToRegister(instr->right()).is(eax)); 2301 ASSERT(ToRegister(instr->right()).is(eax));
2336 ASSERT(ToRegister(instr->result()).is(eax)); 2302 ASSERT(ToRegister(instr->result()).is(eax));
2337 2303
2338 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 2304 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
2339 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2305 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2340 __ nop(); // Signals no inlined code. 2306 __ nop(); // Signals no inlined code.
2341 } 2307 }
2342 2308
2343 2309
2344 int LCodeGen::GetNextEmittedBlock() const {
2345 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2346 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2347 }
2348 return -1;
2349 }
2350
2351
2352 template<class InstrType> 2310 template<class InstrType>
2353 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { 2311 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2354 int left_block = instr->TrueDestination(chunk_); 2312 int left_block = instr->TrueDestination(chunk_);
2355 int right_block = instr->FalseDestination(chunk_); 2313 int right_block = instr->FalseDestination(chunk_);
2356 2314
2357 int next_block = GetNextEmittedBlock(); 2315 int next_block = GetNextEmittedBlock();
2358 2316
2359 if (right_block == left_block || cc == no_condition) { 2317 if (right_block == left_block || cc == no_condition) {
2360 EmitGoto(left_block); 2318 EmitGoto(left_block);
2361 } else if (left_block == next_block) { 2319 } else if (left_block == next_block) {
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 __ bind(&skip_assignment); 3225 __ bind(&skip_assignment);
3268 } 3226 }
3269 3227
3270 3228
3271 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3229 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3272 HObjectAccess access = instr->hydrogen()->access(); 3230 HObjectAccess access = instr->hydrogen()->access();
3273 int offset = access.offset(); 3231 int offset = access.offset();
3274 3232
3275 if (access.IsExternalMemory()) { 3233 if (access.IsExternalMemory()) {
3276 Register result = ToRegister(instr->result()); 3234 Register result = ToRegister(instr->result());
3277 if (instr->object()->IsConstantOperand()) { 3235 MemOperand operand = instr->object()->IsConstantOperand()
3278 ExternalReference external_reference = ToExternalReference( 3236 ? MemOperand::StaticVariable(ToExternalReference(
3279 LConstantOperand::cast(instr->object())); 3237 LConstantOperand::cast(instr->object())))
3280 __ mov(result, MemOperand::StaticVariable(external_reference)); 3238 : MemOperand(ToRegister(instr->object()), offset);
3239 if (access.representation().IsByte()) {
3240 ASSERT(instr->hydrogen()->representation().IsInteger32());
3241 __ movzx_b(result, operand);
3281 } else { 3242 } else {
3282 __ mov(result, MemOperand(ToRegister(instr->object()), offset)); 3243 __ mov(result, operand);
3283 } 3244 }
3284 return; 3245 return;
3285 } 3246 }
3286 3247
3287 Register object = ToRegister(instr->object()); 3248 Register object = ToRegister(instr->object());
3288 if (FLAG_track_double_fields && 3249 if (FLAG_track_double_fields &&
3289 instr->hydrogen()->representation().IsDouble()) { 3250 instr->hydrogen()->representation().IsDouble()) {
3290 if (CpuFeatures::IsSupported(SSE2)) { 3251 if (CpuFeatures::IsSupported(SSE2)) {
3291 CpuFeatureScope scope(masm(), SSE2); 3252 CpuFeatureScope scope(masm(), SSE2);
3292 XMMRegister result = ToDoubleRegister(instr->result()); 3253 XMMRegister result = ToDoubleRegister(instr->result());
3293 __ movdbl(result, FieldOperand(object, offset)); 3254 __ movdbl(result, FieldOperand(object, offset));
3294 } else { 3255 } else {
3295 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); 3256 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset));
3296 } 3257 }
3297 return; 3258 return;
3298 } 3259 }
3299 3260
3300 Register result = ToRegister(instr->result()); 3261 Register result = ToRegister(instr->result());
3301 if (access.IsInobject()) { 3262 if (!access.IsInobject()) {
3263 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
3264 object = result;
3265 }
3266 if (access.representation().IsByte()) {
3267 ASSERT(instr->hydrogen()->representation().IsInteger32());
3268 __ movzx_b(result, FieldOperand(object, offset));
3269 } else {
3302 __ mov(result, FieldOperand(object, offset)); 3270 __ mov(result, FieldOperand(object, offset));
3303 } else {
3304 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
3305 __ mov(result, FieldOperand(result, offset));
3306 } 3271 }
3307 } 3272 }
3308 3273
3309 3274
3310 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 3275 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
3311 ASSERT(!operand->IsDoubleRegister()); 3276 ASSERT(!operand->IsDoubleRegister());
3312 if (operand->IsConstantOperand()) { 3277 if (operand->IsConstantOperand()) {
3313 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); 3278 Handle<Object> object = ToHandle(LConstantOperand::cast(operand));
3314 AllowDeferredHandleDereference smi_check; 3279 AllowDeferredHandleDereference smi_check;
3315 if (object->IsSmi()) { 3280 if (object->IsSmi()) {
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4438 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4403 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4439 __ bind(&done); 4404 __ bind(&done);
4440 } else { 4405 } else {
4441 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); 4406 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
4442 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4407 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4443 } 4408 }
4444 } 4409 }
4445 4410
4446 4411
4447 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4412 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4448 CallRuntime(instr->function(), instr->arity(), instr); 4413 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
4449 } 4414 }
4450 4415
4451 4416
4452 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { 4417 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
4453 Register function = ToRegister(instr->function()); 4418 Register function = ToRegister(instr->function());
4454 Register code_object = ToRegister(instr->code_object()); 4419 Register code_object = ToRegister(instr->code_object());
4455 __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize)); 4420 __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize));
4456 __ mov(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); 4421 __ mov(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object);
4457 } 4422 }
4458 4423
(...skipping 11 matching lines...) Expand all
4470 HObjectAccess access = instr->hydrogen()->access(); 4435 HObjectAccess access = instr->hydrogen()->access();
4471 int offset = access.offset(); 4436 int offset = access.offset();
4472 4437
4473 if (access.IsExternalMemory()) { 4438 if (access.IsExternalMemory()) {
4474 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4439 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4475 MemOperand operand = instr->object()->IsConstantOperand() 4440 MemOperand operand = instr->object()->IsConstantOperand()
4476 ? MemOperand::StaticVariable( 4441 ? MemOperand::StaticVariable(
4477 ToExternalReference(LConstantOperand::cast(instr->object()))) 4442 ToExternalReference(LConstantOperand::cast(instr->object())))
4478 : MemOperand(ToRegister(instr->object()), offset); 4443 : MemOperand(ToRegister(instr->object()), offset);
4479 if (instr->value()->IsConstantOperand()) { 4444 if (instr->value()->IsConstantOperand()) {
4445 ASSERT(!representation.IsByte());
4480 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4446 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4481 __ mov(operand, Immediate(ToInteger32(operand_value))); 4447 __ mov(operand, Immediate(ToInteger32(operand_value)));
4482 } else { 4448 } else {
4483 Register value = ToRegister(instr->value()); 4449 Register value = ToRegister(instr->value());
4484 __ mov(operand, value); 4450 if (representation.IsByte()) {
4451 __ mov_b(operand, value);
4452 } else {
4453 __ mov(operand, value);
4454 }
4485 } 4455 }
4486 return; 4456 return;
4487 } 4457 }
4488 4458
4489 Register object = ToRegister(instr->object()); 4459 Register object = ToRegister(instr->object());
4490 Handle<Map> transition = instr->transition(); 4460 Handle<Map> transition = instr->transition();
4491 4461
4492 if (FLAG_track_fields && representation.IsSmi()) { 4462 if (FLAG_track_fields && representation.IsSmi()) {
4493 if (instr->value()->IsConstantOperand()) { 4463 if (instr->value()->IsConstantOperand()) {
4494 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4464 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4547 SmiCheck check_needed = 4517 SmiCheck check_needed =
4548 instr->hydrogen()->value()->IsHeapObject() 4518 instr->hydrogen()->value()->IsHeapObject()
4549 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4519 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4550 4520
4551 Register write_register = object; 4521 Register write_register = object;
4552 if (!access.IsInobject()) { 4522 if (!access.IsInobject()) {
4553 write_register = ToRegister(instr->temp()); 4523 write_register = ToRegister(instr->temp());
4554 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 4524 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
4555 } 4525 }
4556 4526
4527 MemOperand operand = FieldOperand(write_register, offset);
4557 if (instr->value()->IsConstantOperand()) { 4528 if (instr->value()->IsConstantOperand()) {
4558 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4529 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4559 if (operand_value->IsRegister()) { 4530 if (operand_value->IsRegister()) {
4560 __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); 4531 Register value = ToRegister(operand_value);
4532 if (representation.IsByte()) {
4533 __ mov_b(operand, value);
4534 } else {
4535 __ mov(operand, value);
4536 }
4561 } else { 4537 } else {
4562 Handle<Object> handle_value = ToHandle(operand_value); 4538 Handle<Object> handle_value = ToHandle(operand_value);
4563 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4539 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4564 __ mov(FieldOperand(write_register, offset), handle_value); 4540 __ mov(operand, handle_value);
4565 } 4541 }
4566 } else { 4542 } else {
4567 __ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); 4543 Register value = ToRegister(instr->value());
4544 if (representation.IsByte()) {
4545 __ mov_b(operand, value);
4546 } else {
4547 __ mov(operand, value);
4548 }
4568 } 4549 }
4569 4550
4570 if (instr->hydrogen()->NeedsWriteBarrier()) { 4551 if (instr->hydrogen()->NeedsWriteBarrier()) {
4571 Register value = ToRegister(instr->value()); 4552 Register value = ToRegister(instr->value());
4572 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; 4553 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4573 // Update the write barrier for the object for in-object properties. 4554 // Update the write barrier for the object for in-object properties.
4574 __ RecordWriteField(write_register, 4555 __ RecordWriteField(write_register,
4575 offset, 4556 offset,
4576 value, 4557 value,
4577 temp, 4558 temp,
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
5030 Register input = ToRegister(instr->value()); 5011 Register input = ToRegister(instr->value());
5031 __ SmiTag(input); 5012 __ SmiTag(input);
5032 if (!instr->hydrogen()->value()->HasRange() || 5013 if (!instr->hydrogen()->value()->HasRange() ||
5033 !instr->hydrogen()->value()->range()->IsInSmiRange()) { 5014 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
5034 DeoptimizeIf(overflow, instr->environment()); 5015 DeoptimizeIf(overflow, instr->environment());
5035 } 5016 }
5036 } 5017 }
5037 5018
5038 5019
5039 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 5020 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
5040 CpuFeatureScope scope(masm(), SSE2);
5041 LOperand* input = instr->value(); 5021 LOperand* input = instr->value();
5042 LOperand* output = instr->result(); 5022 LOperand* output = instr->result();
5043 LOperand* temp = instr->temp(); 5023 if (CpuFeatures::IsSupported(SSE2)) {
5024 CpuFeatureScope scope(masm(), SSE2);
5025 LOperand* temp = instr->temp();
5044 5026
5045 __ LoadUint32(ToDoubleRegister(output), 5027 __ LoadUint32(ToDoubleRegister(output),
5046 ToRegister(input), 5028 ToRegister(input),
5047 ToDoubleRegister(temp)); 5029 ToDoubleRegister(temp));
5030 } else {
5031 X87Register res = ToX87Register(output);
5032 X87PrepareToWrite(res);
5033 __ LoadUint32NoSSE2(ToRegister(input));
5034 X87CommitWrite(res);
5035 }
5048 } 5036 }
5049 5037
5050 5038
5051 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 5039 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
5052 class DeferredNumberTagI V8_FINAL : public LDeferredCode { 5040 class DeferredNumberTagI V8_FINAL : public LDeferredCode {
5053 public: 5041 public:
5054 DeferredNumberTagI(LCodeGen* codegen, 5042 DeferredNumberTagI(LCodeGen* codegen,
5055 LNumberTagI* instr, 5043 LNumberTagI* instr,
5056 const X87Stack& x87_stack) 5044 const X87Stack& x87_stack)
5057 : LDeferredCode(codegen, x87_stack), instr_(instr) { } 5045 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
6186 __ j(not_equal, &check_frame_marker, Label::kNear); 6174 __ j(not_equal, &check_frame_marker, Label::kNear);
6187 __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 6175 __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
6188 6176
6189 // Check the marker in the calling frame. 6177 // Check the marker in the calling frame.
6190 __ bind(&check_frame_marker); 6178 __ bind(&check_frame_marker);
6191 __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 6179 __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
6192 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 6180 Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
6193 } 6181 }
6194 6182
6195 6183
6196 void LCodeGen::EnsureSpaceForLazyDeopt() { 6184 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
6197 if (!info()->IsStub()) { 6185 if (!info()->IsStub()) {
6198 // Ensure that we have enough space after the previous lazy-bailout 6186 // Ensure that we have enough space after the previous lazy-bailout
6199 // instruction for patching the code here. 6187 // instruction for patching the code here.
6200 int current_pc = masm()->pc_offset(); 6188 int current_pc = masm()->pc_offset();
6201 int patch_size = Deoptimizer::patch_size(); 6189 if (current_pc < last_lazy_deopt_pc_ + space_needed) {
6202 if (current_pc < last_lazy_deopt_pc_ + patch_size) { 6190 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
6203 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
6204 __ Nop(padding_size); 6191 __ Nop(padding_size);
6205 } 6192 }
6206 } 6193 }
6207 last_lazy_deopt_pc_ = masm()->pc_offset(); 6194 last_lazy_deopt_pc_ = masm()->pc_offset();
6208 } 6195 }
6209 6196
6210 6197
6211 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 6198 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
6212 EnsureSpaceForLazyDeopt(); 6199 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
6213 ASSERT(instr->HasEnvironment()); 6200 ASSERT(instr->HasEnvironment());
6214 LEnvironment* env = instr->environment(); 6201 LEnvironment* env = instr->environment();
6215 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 6202 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
6216 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 6203 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
6217 } 6204 }
6218 6205
6219 6206
6220 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 6207 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
6221 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 6208 Deoptimizer::BailoutType type = instr->hydrogen()->type();
6222 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 6209 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
6273 ExternalReference stack_limit = 6260 ExternalReference stack_limit =
6274 ExternalReference::address_of_stack_limit(isolate()); 6261 ExternalReference::address_of_stack_limit(isolate());
6275 __ cmp(esp, Operand::StaticVariable(stack_limit)); 6262 __ cmp(esp, Operand::StaticVariable(stack_limit));
6276 __ j(above_equal, &done, Label::kNear); 6263 __ j(above_equal, &done, Label::kNear);
6277 6264
6278 ASSERT(instr->context()->IsRegister()); 6265 ASSERT(instr->context()->IsRegister());
6279 ASSERT(ToRegister(instr->context()).is(esi)); 6266 ASSERT(ToRegister(instr->context()).is(esi));
6280 CallCode(isolate()->builtins()->StackCheck(), 6267 CallCode(isolate()->builtins()->StackCheck(),
6281 RelocInfo::CODE_TARGET, 6268 RelocInfo::CODE_TARGET,
6282 instr); 6269 instr);
6283 EnsureSpaceForLazyDeopt(); 6270 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
6284 __ bind(&done); 6271 __ bind(&done);
6285 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 6272 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
6286 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 6273 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
6287 } else { 6274 } else {
6288 ASSERT(instr->hydrogen()->is_backwards_branch()); 6275 ASSERT(instr->hydrogen()->is_backwards_branch());
6289 // Perform stack overflow check if this goto needs it before jumping. 6276 // Perform stack overflow check if this goto needs it before jumping.
6290 DeferredStackCheck* deferred_stack_check = 6277 DeferredStackCheck* deferred_stack_check =
6291 new(zone()) DeferredStackCheck(this, instr, x87_stack_); 6278 new(zone()) DeferredStackCheck(this, instr, x87_stack_);
6292 ExternalReference stack_limit = 6279 ExternalReference stack_limit =
6293 ExternalReference::address_of_stack_limit(isolate()); 6280 ExternalReference::address_of_stack_limit(isolate());
6294 __ cmp(esp, Operand::StaticVariable(stack_limit)); 6281 __ cmp(esp, Operand::StaticVariable(stack_limit));
6295 __ j(below, deferred_stack_check->entry()); 6282 __ j(below, deferred_stack_check->entry());
6296 EnsureSpaceForLazyDeopt(); 6283 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
6297 __ bind(instr->done_label()); 6284 __ bind(instr->done_label());
6298 deferred_stack_check->SetExit(instr->done_label()); 6285 deferred_stack_check->SetExit(instr->done_label());
6299 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 6286 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
6300 // Don't record a deoptimization index for the safepoint here. 6287 // Don't record a deoptimization index for the safepoint here.
6301 // This will be done explicitly when emitting call and the safepoint in 6288 // This will be done explicitly when emitting call and the safepoint in
6302 // the deferred code. 6289 // the deferred code.
6303 } 6290 }
6304 } 6291 }
6305 6292
6306 6293
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
6404 FixedArray::kHeaderSize - kPointerSize)); 6391 FixedArray::kHeaderSize - kPointerSize));
6405 __ bind(&done); 6392 __ bind(&done);
6406 } 6393 }
6407 6394
6408 6395
6409 #undef __ 6396 #undef __
6410 6397
6411 } } // namespace v8::internal 6398 } } // namespace v8::internal
6412 6399
6413 #endif // V8_TARGET_ARCH_IA32 6400 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698