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

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

Issue 6606002: Merge revision 6500-6600 from bleeding_edge to the isolates branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 19 matching lines...) Expand all
30 #if defined(V8_TARGET_ARCH_IA32) 30 #if defined(V8_TARGET_ARCH_IA32)
31 31
32 #include "ia32/lithium-codegen-ia32.h" 32 #include "ia32/lithium-codegen-ia32.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "stub-cache.h" 34 #include "stub-cache.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 // When invoking builtins, we need to record the safepoint in the middle of
41 // the invoke instruction sequence generated by the macro assembler.
40 class SafepointGenerator : public PostCallGenerator { 42 class SafepointGenerator : public PostCallGenerator {
41 public: 43 public:
42 SafepointGenerator(LCodeGen* codegen, 44 SafepointGenerator(LCodeGen* codegen,
43 LPointerMap* pointers, 45 LPointerMap* pointers,
44 int deoptimization_index) 46 int deoptimization_index)
45 : codegen_(codegen), 47 : codegen_(codegen),
46 pointers_(pointers), 48 pointers_(pointers),
47 deoptimization_index_(deoptimization_index) { } 49 deoptimization_index_(deoptimization_index) { }
48 virtual ~SafepointGenerator() { } 50 virtual ~SafepointGenerator() { }
49 51
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 translation->StoreLiteral(src_index); 361 translation->StoreLiteral(src_index);
360 } else { 362 } else {
361 UNREACHABLE(); 363 UNREACHABLE();
362 } 364 }
363 } 365 }
364 366
365 367
366 void LCodeGen::CallCode(Handle<Code> code, 368 void LCodeGen::CallCode(Handle<Code> code,
367 RelocInfo::Mode mode, 369 RelocInfo::Mode mode,
368 LInstruction* instr) { 370 LInstruction* instr) {
369 if (instr != NULL) { 371 ASSERT(instr != NULL);
370 LPointerMap* pointers = instr->pointer_map(); 372 LPointerMap* pointers = instr->pointer_map();
371 RecordPosition(pointers->position()); 373 RecordPosition(pointers->position());
372 __ call(code, mode); 374 __ call(code, mode);
373 RegisterLazyDeoptimization(instr); 375 RegisterLazyDeoptimization(instr);
374 } else {
375 LPointerMap no_pointers(0);
376 RecordPosition(no_pointers.position());
377 __ call(code, mode);
378 RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex);
379 }
380 376
381 // Signal that we don't inline smi code before these stubs in the 377 // Signal that we don't inline smi code before these stubs in the
382 // optimizing code generator. 378 // optimizing code generator.
383 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC || 379 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC ||
384 code->kind() == Code::COMPARE_IC) { 380 code->kind() == Code::COMPARE_IC) {
385 __ nop(); 381 __ nop();
386 } 382 }
387 } 383 }
388 384
389 385
390 void LCodeGen::CallRuntime(const Runtime::Function* function, 386 void LCodeGen::CallRuntime(const Runtime::Function* function,
391 int num_arguments, 387 int num_arguments,
392 LInstruction* instr) { 388 LInstruction* instr) {
393 ASSERT(instr != NULL); 389 ASSERT(instr != NULL);
390 ASSERT(instr->HasPointerMap());
394 LPointerMap* pointers = instr->pointer_map(); 391 LPointerMap* pointers = instr->pointer_map();
395 ASSERT(pointers != NULL);
396 RecordPosition(pointers->position()); 392 RecordPosition(pointers->position());
397 393
398 __ CallRuntime(function, num_arguments); 394 __ CallRuntime(function, num_arguments);
399 // Runtime calls to Throw are not supposed to ever return at the 395 RegisterLazyDeoptimization(instr);
400 // call site, so don't register lazy deoptimization for these. We do
401 // however have to record a safepoint since throwing exceptions can
402 // cause garbage collections.
403 // BUG(3243555): register a lazy deoptimization point at throw. We need
404 // it to be able to inline functions containing a throw statement.
405 if (!instr->IsThrow()) {
406 RegisterLazyDeoptimization(instr);
407 } else {
408 RecordSafepoint(instr->pointer_map(), Safepoint::kNoDeoptimizationIndex);
409 }
410 } 396 }
411 397
412 398
413 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) { 399 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) {
414 // Create the environment to bailout to. If the call has side effects 400 // Create the environment to bailout to. If the call has side effects
415 // execution has to continue after the call otherwise execution can continue 401 // execution has to continue after the call otherwise execution can continue
416 // from a previous bailout point repeating the call. 402 // from a previous bailout point repeating the call.
417 LEnvironment* deoptimization_environment; 403 LEnvironment* deoptimization_environment;
418 if (instr->HasDeoptimizationEnvironment()) { 404 if (instr->HasDeoptimizationEnvironment()) {
419 deoptimization_environment = instr->deoptimization_environment(); 405 deoptimization_environment = instr->deoptimization_environment();
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 for (int i = 0, length = inlined_closures->length(); 545 for (int i = 0, length = inlined_closures->length();
560 i < length; 546 i < length;
561 i++) { 547 i++) {
562 DefineDeoptimizationLiteral(inlined_closures->at(i)); 548 DefineDeoptimizationLiteral(inlined_closures->at(i));
563 } 549 }
564 550
565 inlined_function_count_ = deoptimization_literals_.length(); 551 inlined_function_count_ = deoptimization_literals_.length();
566 } 552 }
567 553
568 554
555 void LCodeGen::RecordSafepoint(
556 LPointerMap* pointers,
557 Safepoint::Kind kind,
558 int arguments,
559 int deoptimization_index) {
560 const ZoneList<LOperand*>* operands = pointers->operands();
561 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
562 kind, arguments, deoptimization_index);
563 for (int i = 0; i < operands->length(); i++) {
564 LOperand* pointer = operands->at(i);
565 if (pointer->IsStackSlot()) {
566 safepoint.DefinePointerSlot(pointer->index());
567 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
568 safepoint.DefinePointerRegister(ToRegister(pointer));
569 }
570 }
571 if (kind & Safepoint::kWithRegisters) {
572 // Register esi always contains a pointer to the context.
573 safepoint.DefinePointerRegister(esi);
574 }
575 }
576
577
569 void LCodeGen::RecordSafepoint(LPointerMap* pointers, 578 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
570 int deoptimization_index) { 579 int deoptimization_index) {
571 const ZoneList<LOperand*>* operands = pointers->operands(); 580 RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index);
572 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
573 deoptimization_index);
574 for (int i = 0; i < operands->length(); i++) {
575 LOperand* pointer = operands->at(i);
576 if (pointer->IsStackSlot()) {
577 safepoint.DefinePointerSlot(pointer->index());
578 }
579 }
580 } 581 }
581 582
582 583
583 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 584 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
584 int arguments, 585 int arguments,
585 int deoptimization_index) { 586 int deoptimization_index) {
586 const ZoneList<LOperand*>* operands = pointers->operands(); 587 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments,
587 Safepoint safepoint = 588 deoptimization_index);
588 safepoints_.DefineSafepointWithRegisters(
589 masm(), arguments, deoptimization_index);
590 for (int i = 0; i < operands->length(); i++) {
591 LOperand* pointer = operands->at(i);
592 if (pointer->IsStackSlot()) {
593 safepoint.DefinePointerSlot(pointer->index());
594 } else if (pointer->IsRegister()) {
595 safepoint.DefinePointerRegister(ToRegister(pointer));
596 }
597 }
598 // Register esi always contains a pointer to the context.
599 safepoint.DefinePointerRegister(esi);
600 } 589 }
601 590
602 591
603 void LCodeGen::RecordPosition(int position) { 592 void LCodeGen::RecordPosition(int position) {
604 if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return; 593 if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return;
605 masm()->positions_recorder()->RecordPosition(position); 594 masm()->positions_recorder()->RecordPosition(position);
606 } 595 }
607 596
608 597
609 void LCodeGen::DoLabel(LLabel* label) { 598 void LCodeGen::DoLabel(LLabel* label) {
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); 1890 __ mov(result, Operand::Cell(instr->hydrogen()->cell()));
1902 if (instr->hydrogen()->check_hole_value()) { 1891 if (instr->hydrogen()->check_hole_value()) {
1903 __ cmp(result, FACTORY->the_hole_value()); 1892 __ cmp(result, FACTORY->the_hole_value());
1904 DeoptimizeIf(equal, instr->environment()); 1893 DeoptimizeIf(equal, instr->environment());
1905 } 1894 }
1906 } 1895 }
1907 1896
1908 1897
1909 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { 1898 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
1910 Register value = ToRegister(instr->InputAt(0)); 1899 Register value = ToRegister(instr->InputAt(0));
1911 __ mov(Operand::Cell(instr->hydrogen()->cell()), value); 1900 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell());
1901
1902 // If the cell we are storing to contains the hole it could have
1903 // been deleted from the property dictionary. In that case, we need
1904 // to update the property details in the property dictionary to mark
1905 // it as no longer deleted. We deoptimize in that case.
1906 if (instr->hydrogen()->check_hole_value()) {
1907 __ cmp(cell_operand, FACTORY->the_hole_value());
1908 DeoptimizeIf(equal, instr->environment());
1909 }
1910
1911 // Store the value.
1912 __ mov(cell_operand, value);
1912 } 1913 }
1913 1914
1914 1915
1915 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 1916 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
1916 // TODO(antonm): load a context with a separate instruction. 1917 // TODO(antonm): load a context with a separate instruction.
1917 Register result = ToRegister(instr->result()); 1918 Register result = ToRegister(instr->result());
1918 __ LoadContext(result, instr->context_chain_length()); 1919 __ LoadContext(result, instr->context_chain_length());
1919 __ mov(result, ContextOperand(result, instr->slot_index())); 1920 __ mov(result, ContextOperand(result, instr->slot_index()));
1920 } 1921 }
1921 1922
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 // length is a small non-negative integer, due to the test above. 2126 // length is a small non-negative integer, due to the test above.
2126 __ test(length, Operand(length)); 2127 __ test(length, Operand(length));
2127 __ j(zero, &invoke); 2128 __ j(zero, &invoke);
2128 __ bind(&loop); 2129 __ bind(&loop);
2129 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 2130 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
2130 __ dec(length); 2131 __ dec(length);
2131 __ j(not_zero, &loop); 2132 __ j(not_zero, &loop);
2132 2133
2133 // Invoke the function. 2134 // Invoke the function.
2134 __ bind(&invoke); 2135 __ bind(&invoke);
2136 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
2137 LPointerMap* pointers = instr->pointer_map();
2138 LEnvironment* env = instr->deoptimization_environment();
2139 RecordPosition(pointers->position());
2140 RegisterEnvironmentForDeoptimization(env);
2141 SafepointGenerator safepoint_generator(this,
2142 pointers,
2143 env->deoptimization_index());
2135 ASSERT(receiver.is(eax)); 2144 ASSERT(receiver.is(eax));
2136 v8::internal::ParameterCount actual(eax); 2145 v8::internal::ParameterCount actual(eax);
2137 SafepointGenerator safepoint_generator(this,
2138 instr->pointer_map(),
2139 Safepoint::kNoDeoptimizationIndex);
2140 __ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator); 2146 __ InvokeFunction(edi, actual, CALL_FUNCTION, &safepoint_generator);
2141 } 2147 }
2142 2148
2143 2149
2144 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2150 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2145 LOperand* argument = instr->InputAt(0); 2151 LOperand* argument = instr->InputAt(0);
2146 if (argument->IsConstantOperand()) { 2152 if (argument->IsConstantOperand()) {
2147 __ push(ToImmediate(argument)); 2153 __ push(ToImmediate(argument));
2148 } else { 2154 } else {
2149 __ push(ToOperand(argument)); 2155 __ push(ToOperand(argument));
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 2383
2378 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 2384 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2379 XMMRegister xmm_scratch = xmm0; 2385 XMMRegister xmm_scratch = xmm0;
2380 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2386 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2381 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2387 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2382 ExternalReference negative_infinity = 2388 ExternalReference negative_infinity =
2383 ExternalReference::address_of_negative_infinity(); 2389 ExternalReference::address_of_negative_infinity();
2384 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity)); 2390 __ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
2385 __ ucomisd(xmm_scratch, input_reg); 2391 __ ucomisd(xmm_scratch, input_reg);
2386 DeoptimizeIf(equal, instr->environment()); 2392 DeoptimizeIf(equal, instr->environment());
2393 __ xorpd(xmm_scratch, xmm_scratch);
2394 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
2387 __ sqrtsd(input_reg, input_reg); 2395 __ sqrtsd(input_reg, input_reg);
2388 } 2396 }
2389 2397
2390 2398
2391 void LCodeGen::DoPower(LPower* instr) { 2399 void LCodeGen::DoPower(LPower* instr) {
2392 LOperand* left = instr->InputAt(0); 2400 LOperand* left = instr->InputAt(0);
2393 LOperand* right = instr->InputAt(1); 2401 LOperand* right = instr->InputAt(1);
2394 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 2402 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2395 Representation exponent_type = instr->hydrogen()->right()->representation(); 2403 Representation exponent_type = instr->hydrogen()->right()->representation();
2396 if (exponent_type.IsDouble()) { 2404 if (exponent_type.IsDouble()) {
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 3569
3562 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { 3570 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
3563 LOperand* obj = instr->object(); 3571 LOperand* obj = instr->object();
3564 LOperand* key = instr->key(); 3572 LOperand* key = instr->key();
3565 __ push(ToOperand(obj)); 3573 __ push(ToOperand(obj));
3566 if (key->IsConstantOperand()) { 3574 if (key->IsConstantOperand()) {
3567 __ push(ToImmediate(key)); 3575 __ push(ToImmediate(key));
3568 } else { 3576 } else {
3569 __ push(ToOperand(key)); 3577 __ push(ToOperand(key));
3570 } 3578 }
3571 RecordPosition(instr->pointer_map()->position()); 3579 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
3580 LPointerMap* pointers = instr->pointer_map();
3581 LEnvironment* env = instr->deoptimization_environment();
3582 RecordPosition(pointers->position());
3583 RegisterEnvironmentForDeoptimization(env);
3572 SafepointGenerator safepoint_generator(this, 3584 SafepointGenerator safepoint_generator(this,
3573 instr->pointer_map(), 3585 pointers,
3574 Safepoint::kNoDeoptimizationIndex); 3586 env->deoptimization_index());
3575 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator); 3587 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
3576 } 3588 }
3577 3589
3578 3590
3579 void LCodeGen::DoStackCheck(LStackCheck* instr) { 3591 void LCodeGen::DoStackCheck(LStackCheck* instr) {
3580 // Perform stack overflow check. 3592 // Perform stack overflow check.
3581 NearLabel done; 3593 NearLabel done;
3582 ExternalReference stack_limit = ExternalReference::address_of_stack_limit(); 3594 ExternalReference stack_limit = ExternalReference::address_of_stack_limit();
3583 __ cmp(esp, Operand::StaticVariable(stack_limit)); 3595 __ cmp(esp, Operand::StaticVariable(stack_limit));
3584 __ j(above_equal, &done); 3596 __ j(above_equal, &done);
(...skipping 19 matching lines...) Expand all
3604 ASSERT(osr_pc_offset_ == -1); 3616 ASSERT(osr_pc_offset_ == -1);
3605 osr_pc_offset_ = masm()->pc_offset(); 3617 osr_pc_offset_ = masm()->pc_offset();
3606 } 3618 }
3607 3619
3608 3620
3609 #undef __ 3621 #undef __
3610 3622
3611 } } // namespace v8::internal 3623 } } // namespace v8::internal
3612 3624
3613 #endif // V8_TARGET_ARCH_IA32 3625 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/ast.cc ('K') | « 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