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

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

Issue 293743005: Introduce x87 port (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x87/frames-x87.cc ('k') | src/x87/ic-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_X87
8 8
9 #include "code-stubs.h" 9 #include "code-stubs.h"
10 #include "codegen.h" 10 #include "codegen.h"
11 #include "compiler.h" 11 #include "compiler.h"
12 #include "debug.h" 12 #include "debug.h"
13 #include "full-codegen.h" 13 #include "full-codegen.h"
14 #include "isolate-inl.h" 14 #include "isolate-inl.h"
15 #include "parser.h" 15 #include "parser.h"
16 #include "scopes.h" 16 #include "scopes.h"
17 #include "stub-cache.h" 17 #include "stub-cache.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 // return address on top of them. The actual argument count matches the 104 // return address on top of them. The actual argument count matches the
105 // formal parameter count expected by the function. 105 // formal parameter count expected by the function.
106 // 106 //
107 // The live registers are: 107 // The live registers are:
108 // o edi: the JS function object being called (i.e. ourselves) 108 // o edi: the JS function object being called (i.e. ourselves)
109 // o esi: our context 109 // o esi: our context
110 // o ebp: our caller's frame pointer 110 // o ebp: our caller's frame pointer
111 // o esp: stack pointer (pointing to return address) 111 // o esp: stack pointer (pointing to return address)
112 // 112 //
113 // The function builds a JS frame. Please see JavaScriptFrameConstants in 113 // The function builds a JS frame. Please see JavaScriptFrameConstants in
114 // frames-ia32.h for its layout. 114 // frames-x87.h for its layout.
115 void FullCodeGenerator::Generate() { 115 void FullCodeGenerator::Generate() {
116 CompilationInfo* info = info_; 116 CompilationInfo* info = info_;
117 handler_table_ = 117 handler_table_ =
118 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 118 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
119 119
120 profiling_counter_ = isolate()->factory()->NewCell( 120 profiling_counter_ = isolate()->factory()->NewCell(
121 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 121 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
122 SetFunctionPosition(function()); 122 SetFunctionPosition(function());
123 Comment cmnt(masm_, "[ function compiled by full code generator"); 123 Comment cmnt(masm_, "[ function compiled by full code generator");
124 124
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 (num_parameters - 1 - i) * kPointerSize; 225 (num_parameters - 1 - i) * kPointerSize;
226 // Load parameter from stack. 226 // Load parameter from stack.
227 __ mov(eax, Operand(ebp, parameter_offset)); 227 __ mov(eax, Operand(ebp, parameter_offset));
228 // Store it in the context. 228 // Store it in the context.
229 int context_offset = Context::SlotOffset(var->index()); 229 int context_offset = Context::SlotOffset(var->index());
230 __ mov(Operand(esi, context_offset), eax); 230 __ mov(Operand(esi, context_offset), eax);
231 // Update the write barrier. This clobbers eax and ebx. 231 // Update the write barrier. This clobbers eax and ebx.
232 __ RecordWriteContextSlot(esi, 232 __ RecordWriteContextSlot(esi,
233 context_offset, 233 context_offset,
234 eax, 234 eax,
235 ebx, 235 ebx);
236 kDontSaveFPRegs);
237 } 236 }
238 } 237 }
239 } 238 }
240 239
241 Variable* arguments = scope()->arguments(); 240 Variable* arguments = scope()->arguments();
242 if (arguments != NULL) { 241 if (arguments != NULL) {
243 // Function uses arguments object. 242 // Function uses arguments object.
244 Comment cmnt(masm_, "[ Allocate arguments object"); 243 Comment cmnt(masm_, "[ Allocate arguments object");
245 if (function_in_register) { 244 if (function_in_register) {
246 __ push(edi); 245 __ push(edi);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 440
442 void FullCodeGenerator::TestContext::Plug(Variable* var) const { 441 void FullCodeGenerator::TestContext::Plug(Variable* var) const {
443 // For simplicity we always test the accumulator register. 442 // For simplicity we always test the accumulator register.
444 codegen()->GetVar(result_register(), var); 443 codegen()->GetVar(result_register(), var);
445 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 444 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
446 codegen()->DoTest(this); 445 codegen()->DoTest(this);
447 } 446 }
448 447
449 448
450 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 449 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
451 UNREACHABLE(); // Not used on IA32. 450 UNREACHABLE(); // Not used on X87.
452 } 451 }
453 452
454 453
455 void FullCodeGenerator::AccumulatorValueContext::Plug( 454 void FullCodeGenerator::AccumulatorValueContext::Plug(
456 Heap::RootListIndex index) const { 455 Heap::RootListIndex index) const {
457 UNREACHABLE(); // Not used on IA32. 456 UNREACHABLE(); // Not used on X87.
458 } 457 }
459 458
460 459
461 void FullCodeGenerator::StackValueContext::Plug( 460 void FullCodeGenerator::StackValueContext::Plug(
462 Heap::RootListIndex index) const { 461 Heap::RootListIndex index) const {
463 UNREACHABLE(); // Not used on IA32. 462 UNREACHABLE(); // Not used on X87.
464 } 463 }
465 464
466 465
467 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 466 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
468 UNREACHABLE(); // Not used on IA32. 467 UNREACHABLE(); // Not used on X87.
469 } 468 }
470 469
471 470
472 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const { 471 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {
473 } 472 }
474 473
475 474
476 void FullCodeGenerator::AccumulatorValueContext::Plug( 475 void FullCodeGenerator::AccumulatorValueContext::Plug(
477 Handle<Object> lit) const { 476 Handle<Object> lit) const {
478 if (lit->IsSmi()) { 477 if (lit->IsSmi()) {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 ASSERT(!scratch0.is(src)); 697 ASSERT(!scratch0.is(src));
699 ASSERT(!scratch0.is(scratch1)); 698 ASSERT(!scratch0.is(scratch1));
700 ASSERT(!scratch1.is(src)); 699 ASSERT(!scratch1.is(src));
701 MemOperand location = VarOperand(var, scratch0); 700 MemOperand location = VarOperand(var, scratch0);
702 __ mov(location, src); 701 __ mov(location, src);
703 702
704 // Emit the write barrier code if the location is in the heap. 703 // Emit the write barrier code if the location is in the heap.
705 if (var->IsContextSlot()) { 704 if (var->IsContextSlot()) {
706 int offset = Context::SlotOffset(var->index()); 705 int offset = Context::SlotOffset(var->index());
707 ASSERT(!scratch0.is(esi) && !src.is(esi) && !scratch1.is(esi)); 706 ASSERT(!scratch0.is(esi) && !src.is(esi) && !scratch1.is(esi));
708 __ RecordWriteContextSlot(scratch0, offset, src, scratch1, kDontSaveFPRegs); 707 __ RecordWriteContextSlot(scratch0, offset, src, scratch1);
709 } 708 }
710 } 709 }
711 710
712 711
713 void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, 712 void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
714 bool should_normalize, 713 bool should_normalize,
715 Label* if_true, 714 Label* if_true,
716 Label* if_false) { 715 Label* if_false) {
717 // Only prepare for bailouts before splits if we're in a test 716 // Only prepare for bailouts before splits if we're in a test
718 // context. Otherwise, we let the Visit function deal with the 717 // context. Otherwise, we let the Visit function deal with the
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 case Variable::CONTEXT: { 831 case Variable::CONTEXT: {
833 Comment cmnt(masm_, "[ FunctionDeclaration"); 832 Comment cmnt(masm_, "[ FunctionDeclaration");
834 EmitDebugCheckDeclarationContext(variable); 833 EmitDebugCheckDeclarationContext(variable);
835 VisitForAccumulatorValue(declaration->fun()); 834 VisitForAccumulatorValue(declaration->fun());
836 __ mov(ContextOperand(esi, variable->index()), result_register()); 835 __ mov(ContextOperand(esi, variable->index()), result_register());
837 // We know that we have written a function, which is not a smi. 836 // We know that we have written a function, which is not a smi.
838 __ RecordWriteContextSlot(esi, 837 __ RecordWriteContextSlot(esi,
839 Context::SlotOffset(variable->index()), 838 Context::SlotOffset(variable->index()),
840 result_register(), 839 result_register(),
841 ecx, 840 ecx,
842 kDontSaveFPRegs,
843 EMIT_REMEMBERED_SET, 841 EMIT_REMEMBERED_SET,
844 OMIT_SMI_CHECK); 842 OMIT_SMI_CHECK);
845 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 843 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
846 break; 844 break;
847 } 845 }
848 846
849 case Variable::LOOKUP: { 847 case Variable::LOOKUP: {
850 Comment cmnt(masm_, "[ FunctionDeclaration"); 848 Comment cmnt(masm_, "[ FunctionDeclaration");
851 __ push(esi); 849 __ push(esi);
852 __ push(Immediate(variable->name())); 850 __ push(Immediate(variable->name()));
(...skipping 19 matching lines...) Expand all
872 __ mov(eax, ContextOperand(eax, variable->interface()->Index())); 870 __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
873 __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX)); 871 __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
874 872
875 // Assign it. 873 // Assign it.
876 __ mov(ContextOperand(esi, variable->index()), eax); 874 __ mov(ContextOperand(esi, variable->index()), eax);
877 // We know that we have written a module, which is not a smi. 875 // We know that we have written a module, which is not a smi.
878 __ RecordWriteContextSlot(esi, 876 __ RecordWriteContextSlot(esi,
879 Context::SlotOffset(variable->index()), 877 Context::SlotOffset(variable->index()),
880 eax, 878 eax,
881 ecx, 879 ecx,
882 kDontSaveFPRegs,
883 EMIT_REMEMBERED_SET, 880 EMIT_REMEMBERED_SET,
884 OMIT_SMI_CHECK); 881 OMIT_SMI_CHECK);
885 PrepareForBailoutForId(declaration->proxy()->id(), NO_REGISTERS); 882 PrepareForBailoutForId(declaration->proxy()->id(), NO_REGISTERS);
886 883
887 // Traverse into body. 884 // Traverse into body.
888 Visit(declaration->module()); 885 Visit(declaration->module());
889 } 886 }
890 887
891 888
892 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { 889 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 if (IsFastObjectElementsKind(constant_elements_kind)) { 1762 if (IsFastObjectElementsKind(constant_elements_kind)) {
1766 // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they 1763 // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they
1767 // cannot transition and don't need to call the runtime stub. 1764 // cannot transition and don't need to call the runtime stub.
1768 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1765 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1769 __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal. 1766 __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal.
1770 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1767 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
1771 // Store the subexpression value in the array's elements. 1768 // Store the subexpression value in the array's elements.
1772 __ mov(FieldOperand(ebx, offset), result_register()); 1769 __ mov(FieldOperand(ebx, offset), result_register());
1773 // Update the write barrier for the array store. 1770 // Update the write barrier for the array store.
1774 __ RecordWriteField(ebx, offset, result_register(), ecx, 1771 __ RecordWriteField(ebx, offset, result_register(), ecx,
1775 kDontSaveFPRegs,
1776 EMIT_REMEMBERED_SET, 1772 EMIT_REMEMBERED_SET,
1777 INLINE_SMI_CHECK); 1773 INLINE_SMI_CHECK);
1778 } else { 1774 } else {
1779 // Store the subexpression value in the array's elements. 1775 // Store the subexpression value in the array's elements.
1780 __ mov(ecx, Immediate(Smi::FromInt(i))); 1776 __ mov(ecx, Immediate(Smi::FromInt(i)));
1781 StoreArrayLiteralElementStub stub(isolate()); 1777 StoreArrayLiteralElementStub stub(isolate());
1782 __ CallStub(&stub); 1778 __ CallStub(&stub);
1783 } 1779 }
1784 1780
1785 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1781 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 __ bind(&continuation); 1920 __ bind(&continuation);
1925 __ jmp(&resume); 1921 __ jmp(&resume);
1926 1922
1927 __ bind(&suspend); 1923 __ bind(&suspend);
1928 VisitForAccumulatorValue(expr->generator_object()); 1924 VisitForAccumulatorValue(expr->generator_object());
1929 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1925 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1930 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), 1926 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
1931 Immediate(Smi::FromInt(continuation.pos()))); 1927 Immediate(Smi::FromInt(continuation.pos())));
1932 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 1928 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi);
1933 __ mov(ecx, esi); 1929 __ mov(ecx, esi);
1934 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1930 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx);
1935 kDontSaveFPRegs);
1936 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1931 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1937 __ cmp(esp, ebx); 1932 __ cmp(esp, ebx);
1938 __ j(equal, &post_runtime); 1933 __ j(equal, &post_runtime);
1939 __ push(eax); // generator object 1934 __ push(eax); // generator object
1940 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); 1935 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1);
1941 __ mov(context_register(), 1936 __ mov(context_register(),
1942 Operand(ebp, StandardFrameConstants::kContextOffset)); 1937 Operand(ebp, StandardFrameConstants::kContextOffset));
1943 __ bind(&post_runtime); 1938 __ bind(&post_runtime);
1944 __ pop(result_register()); 1939 __ pop(result_register());
1945 EmitReturnSequence(); 1940 EmitReturnSequence();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 __ jmp(&l_resume); 1991 __ jmp(&l_resume);
1997 __ bind(&l_suspend); 1992 __ bind(&l_suspend);
1998 const int generator_object_depth = kPointerSize + handler_size; 1993 const int generator_object_depth = kPointerSize + handler_size;
1999 __ mov(eax, Operand(esp, generator_object_depth)); 1994 __ mov(eax, Operand(esp, generator_object_depth));
2000 __ push(eax); // g 1995 __ push(eax); // g
2001 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); 1996 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
2002 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), 1997 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
2003 Immediate(Smi::FromInt(l_continuation.pos()))); 1998 Immediate(Smi::FromInt(l_continuation.pos())));
2004 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 1999 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi);
2005 __ mov(ecx, esi); 2000 __ mov(ecx, esi);
2006 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 2001 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx);
2007 kDontSaveFPRegs);
2008 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); 2002 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1);
2009 __ mov(context_register(), 2003 __ mov(context_register(),
2010 Operand(ebp, StandardFrameConstants::kContextOffset)); 2004 Operand(ebp, StandardFrameConstants::kContextOffset));
2011 __ pop(eax); // result 2005 __ pop(eax); // result
2012 EmitReturnSequence(); 2006 EmitReturnSequence();
2013 __ bind(&l_resume); // received in eax 2007 __ bind(&l_resume); // received in eax
2014 __ PopTryHandler(); 2008 __ PopTryHandler();
2015 2009
2016 // receiver = iter; f = iter.next; arg = received; 2010 // receiver = iter; f = iter.next; arg = received;
2017 __ bind(&l_next); 2011 __ bind(&l_next);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 2185 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
2192 isolate()->factory()->empty_fixed_array()); 2186 isolate()->factory()->empty_fixed_array());
2193 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 2187 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
2194 isolate()->factory()->empty_fixed_array()); 2188 isolate()->factory()->empty_fixed_array());
2195 __ mov(FieldOperand(eax, JSGeneratorObject::kResultValuePropertyOffset), ecx); 2189 __ mov(FieldOperand(eax, JSGeneratorObject::kResultValuePropertyOffset), ecx);
2196 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); 2190 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx);
2197 2191
2198 // Only the value field needs a write barrier, as the other values are in the 2192 // Only the value field needs a write barrier, as the other values are in the
2199 // root set. 2193 // root set.
2200 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, 2194 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset,
2201 ecx, edx, kDontSaveFPRegs); 2195 ecx, edx);
2202 } 2196 }
2203 2197
2204 2198
2205 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2199 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2206 SetSourcePosition(prop->position()); 2200 SetSourcePosition(prop->position());
2207 Literal* key = prop->key()->AsLiteral(); 2201 Literal* key = prop->key()->AsLiteral();
2208 ASSERT(!key->value()->IsSmi()); 2202 ASSERT(!key->value()->IsSmi());
2209 __ mov(ecx, Immediate(key->value())); 2203 __ mov(ecx, Immediate(key->value()));
2210 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2204 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2211 } 2205 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2372 context()->Plug(eax); 2366 context()->Plug(eax);
2373 } 2367 }
2374 2368
2375 2369
2376 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2370 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2377 Variable* var, MemOperand location) { 2371 Variable* var, MemOperand location) {
2378 __ mov(location, eax); 2372 __ mov(location, eax);
2379 if (var->IsContextSlot()) { 2373 if (var->IsContextSlot()) {
2380 __ mov(edx, eax); 2374 __ mov(edx, eax);
2381 int offset = Context::SlotOffset(var->index()); 2375 int offset = Context::SlotOffset(var->index());
2382 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 2376 __ RecordWriteContextSlot(ecx, offset, edx, ebx);
2383 } 2377 }
2384 } 2378 }
2385 2379
2386 2380
2387 void FullCodeGenerator::EmitCallStoreContextSlot( 2381 void FullCodeGenerator::EmitCallStoreContextSlot(
2388 Handle<String> name, StrictMode strict_mode) { 2382 Handle<String> name, StrictMode strict_mode) {
2389 __ push(eax); // Value. 2383 __ push(eax); // Value.
2390 __ push(esi); // Context. 2384 __ push(esi); // Context.
2391 __ push(Immediate(name)); 2385 __ push(Immediate(name));
2392 __ push(Immediate(Smi::FromInt(strict_mode))); 2386 __ push(Immediate(Smi::FromInt(strict_mode)));
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
3408 } 3402 }
3409 3403
3410 3404
3411 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { 3405 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
3412 // Load the arguments on the stack and call the runtime function. 3406 // Load the arguments on the stack and call the runtime function.
3413 ZoneList<Expression*>* args = expr->arguments(); 3407 ZoneList<Expression*>* args = expr->arguments();
3414 ASSERT(args->length() == 2); 3408 ASSERT(args->length() == 2);
3415 VisitForStackValue(args->at(0)); 3409 VisitForStackValue(args->at(0));
3416 VisitForStackValue(args->at(1)); 3410 VisitForStackValue(args->at(1));
3417 3411
3418 MathPowStub stub(isolate(), MathPowStub::ON_STACK); 3412 __ CallRuntime(Runtime::kHiddenMathPowSlow, 2);
3419 __ CallStub(&stub);
3420 context()->Plug(eax); 3413 context()->Plug(eax);
3421 } 3414 }
3422 3415
3423 3416
3424 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { 3417 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
3425 ZoneList<Expression*>* args = expr->arguments(); 3418 ZoneList<Expression*>* args = expr->arguments();
3426 ASSERT(args->length() == 2); 3419 ASSERT(args->length() == 2);
3427 3420
3428 VisitForStackValue(args->at(0)); // Load the object. 3421 VisitForStackValue(args->at(0)); // Load the object.
3429 VisitForAccumulatorValue(args->at(1)); // Load the value. 3422 VisitForAccumulatorValue(args->at(1)); // Load the value.
3430 __ pop(ebx); // eax = value. ebx = object. 3423 __ pop(ebx); // eax = value. ebx = object.
3431 3424
3432 Label done; 3425 Label done;
3433 // If the object is a smi, return the value. 3426 // If the object is a smi, return the value.
3434 __ JumpIfSmi(ebx, &done, Label::kNear); 3427 __ JumpIfSmi(ebx, &done, Label::kNear);
3435 3428
3436 // If the object is not a value type, return the value. 3429 // If the object is not a value type, return the value.
3437 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 3430 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
3438 __ j(not_equal, &done, Label::kNear); 3431 __ j(not_equal, &done, Label::kNear);
3439 3432
3440 // Store the value. 3433 // Store the value.
3441 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax); 3434 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax);
3442 3435
3443 // Update the write barrier. Save the value as it will be 3436 // Update the write barrier. Save the value as it will be
3444 // overwritten by the write barrier code and is needed afterward. 3437 // overwritten by the write barrier code and is needed afterward.
3445 __ mov(edx, eax); 3438 __ mov(edx, eax);
3446 __ RecordWriteField(ebx, JSValue::kValueOffset, edx, ecx, kDontSaveFPRegs); 3439 __ RecordWriteField(ebx, JSValue::kValueOffset, edx, ecx);
3447 3440
3448 __ bind(&done); 3441 __ bind(&done);
3449 context()->Plug(eax); 3442 context()->Plug(eax);
3450 } 3443 }
3451 3444
3452 3445
3453 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { 3446 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
3454 ZoneList<Expression*>* args = expr->arguments(); 3447 ZoneList<Expression*>* args = expr->arguments();
3455 ASSERT_EQ(args->length(), 1); 3448 ASSERT_EQ(args->length(), 1);
3456 3449
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after
4792 4785
4793 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4786 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4794 Assembler::target_address_at(call_target_address, 4787 Assembler::target_address_at(call_target_address,
4795 unoptimized_code)); 4788 unoptimized_code));
4796 return OSR_AFTER_STACK_CHECK; 4789 return OSR_AFTER_STACK_CHECK;
4797 } 4790 }
4798 4791
4799 4792
4800 } } // namespace v8::internal 4793 } } // namespace v8::internal
4801 4794
4802 #endif // V8_TARGET_ARCH_IA32 4795 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/frames-x87.cc ('k') | src/x87/ic-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698