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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6717018: Introduce accessors on builtins instance (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix tests and lint. 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
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ia32/virtual-frame-ia32.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 Register prototype) { 268 Register prototype) {
269 __ LoadGlobalFunction(index, prototype); 269 __ LoadGlobalFunction(index, prototype);
270 __ LoadGlobalFunctionInitialMap(prototype, prototype); 270 __ LoadGlobalFunctionInitialMap(prototype, prototype);
271 // Load the prototype from the initial map. 271 // Load the prototype from the initial map.
272 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 272 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
273 } 273 }
274 274
275 275
276 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 276 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
277 MacroAssembler* masm, int index, Register prototype, Label* miss) { 277 MacroAssembler* masm, int index, Register prototype, Label* miss) {
278 Isolate* isolate = masm->isolate();
278 // Check we're still in the same context. 279 // Check we're still in the same context.
279 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)), 280 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
280 Isolate::Current()->global()); 281 isolate->global());
281 __ j(not_equal, miss); 282 __ j(not_equal, miss);
282 // Get the global function with the given index. 283 // Get the global function with the given index.
283 JSFunction* function = JSFunction::cast( 284 JSFunction* function =
284 Isolate::Current()->global_context()->get(index)); 285 JSFunction::cast(isolate->global_context()->get(index));
285 // Load its initial map. The global functions all have initial maps. 286 // Load its initial map. The global functions all have initial maps.
286 __ Set(prototype, Immediate(Handle<Map>(function->initial_map()))); 287 __ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
287 // Load the prototype from the initial map. 288 // Load the prototype from the initial map.
288 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 289 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
289 } 290 }
290 291
291 292
292 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 293 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
293 Register receiver, 294 Register receiver,
294 Register scratch, 295 Register scratch,
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 StubCompiler* stub_compiler_; 742 StubCompiler* stub_compiler_;
742 const ParameterCount& arguments_; 743 const ParameterCount& arguments_;
743 Register name_; 744 Register name_;
744 }; 745 };
745 746
746 747
747 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 748 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
748 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 749 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
749 Code* code = NULL; 750 Code* code = NULL;
750 if (kind == Code::LOAD_IC) { 751 if (kind == Code::LOAD_IC) {
751 code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss); 752 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
752 } else { 753 } else {
753 code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss); 754 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
754 } 755 }
755 756
756 Handle<Code> ic(code); 757 Handle<Code> ic(code);
757 __ jmp(ic, RelocInfo::CODE_TARGET); 758 __ jmp(ic, RelocInfo::CODE_TARGET);
758 } 759 }
759 760
760 761
761 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 762 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
762 // but may be destroyed if store is successful. 763 // but may be destroyed if store is successful.
763 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 764 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 __ j(not_equal, miss, not_taken); 1354 __ j(not_equal, miss, not_taken);
1354 } else { 1355 } else {
1355 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1356 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
1356 __ j(not_equal, miss, not_taken); 1357 __ j(not_equal, miss, not_taken);
1357 } 1358 }
1358 } 1359 }
1359 1360
1360 1361
1361 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1362 MaybeObject* CallStubCompiler::GenerateMissBranch() {
1362 MaybeObject* maybe_obj = 1363 MaybeObject* maybe_obj =
1363 Isolate::Current()->stub_cache()->ComputeCallMiss( 1364 masm()->isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1364 arguments().immediate(), kind_); 1365 kind_);
1365 Object* obj; 1366 Object* obj;
1366 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1367 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1367 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1368 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1368 return obj; 1369 return obj;
1369 } 1370 }
1370 1371
1371 1372
1372 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( 1373 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField(
1373 JSObject* object, 1374 JSObject* object,
1374 JSObject* holder, 1375 JSObject* holder,
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 JSFunction* function, 1907 JSFunction* function,
1907 String* name) { 1908 String* name) {
1908 // ----------- S t a t e ------------- 1909 // ----------- S t a t e -------------
1909 // -- ecx : name 1910 // -- ecx : name
1910 // -- esp[0] : return address 1911 // -- esp[0] : return address
1911 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1912 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1912 // -- ... 1913 // -- ...
1913 // -- esp[(argc + 1) * 4] : receiver 1914 // -- esp[(argc + 1) * 4] : receiver
1914 // ----------------------------------- 1915 // -----------------------------------
1915 1916
1916 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2)) 1917 if (masm()->isolate()->cpu_features()->IsSupported(SSE2))
1917 return HEAP->undefined_value(); 1918 return HEAP->undefined_value();
1918 CpuFeatures::Scope use_sse2(SSE2); 1919 CpuFeatures::Scope use_sse2(SSE2);
1919 1920
1920 const int argc = arguments().immediate(); 1921 const int argc = arguments().immediate();
1921 1922
1922 // If the object is not a JSObject or we got an unexpected number of 1923 // If the object is not a JSObject or we got an unexpected number of
1923 // arguments, bail out to the regular call. 1924 // arguments, bail out to the regular call.
1924 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); 1925 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
1925 1926
1926 Label miss; 1927 Label miss;
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 GenerateStoreField(masm(), 2477 GenerateStoreField(masm(),
2477 object, 2478 object,
2478 index, 2479 index,
2479 transition, 2480 transition,
2480 edx, ecx, ebx, 2481 edx, ecx, ebx,
2481 &miss); 2482 &miss);
2482 2483
2483 // Handle store cache miss. 2484 // Handle store cache miss.
2484 __ bind(&miss); 2485 __ bind(&miss);
2485 __ mov(ecx, Immediate(Handle<String>(name))); // restore name 2486 __ mov(ecx, Immediate(Handle<String>(name))); // restore name
2486 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2487 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2487 Builtins::StoreIC_Miss));
2488 __ jmp(ic, RelocInfo::CODE_TARGET); 2488 __ jmp(ic, RelocInfo::CODE_TARGET);
2489 2489
2490 // Return the generated code. 2490 // Return the generated code.
2491 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2491 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2492 } 2492 }
2493 2493
2494 2494
2495 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2495 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object,
2496 AccessorInfo* callback, 2496 AccessorInfo* callback,
2497 String* name) { 2497 String* name) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2529 __ push(ebx); // restore return address 2529 __ push(ebx); // restore return address
2530 2530
2531 // Do tail-call to the runtime system. 2531 // Do tail-call to the runtime system.
2532 Isolate* isolate = masm()->isolate(); 2532 Isolate* isolate = masm()->isolate();
2533 ExternalReference store_callback_property = 2533 ExternalReference store_callback_property =
2534 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate); 2534 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate);
2535 __ TailCallExternalReference(store_callback_property, 4, 1); 2535 __ TailCallExternalReference(store_callback_property, 4, 1);
2536 2536
2537 // Handle store cache miss. 2537 // Handle store cache miss.
2538 __ bind(&miss); 2538 __ bind(&miss);
2539 Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss)); 2539 Handle<Code> ic = isolate->builtins()->StoreIC_Miss();
2540 __ jmp(ic, RelocInfo::CODE_TARGET); 2540 __ jmp(ic, RelocInfo::CODE_TARGET);
2541 2541
2542 // Return the generated code. 2542 // Return the generated code.
2543 return GetCode(CALLBACKS, name); 2543 return GetCode(CALLBACKS, name);
2544 } 2544 }
2545 2545
2546 2546
2547 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2547 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
2548 String* name) { 2548 String* name) {
2549 // ----------- S t a t e ------------- 2549 // ----------- S t a t e -------------
(...skipping 30 matching lines...) Expand all
2580 __ push(ebx); // restore return address 2580 __ push(ebx); // restore return address
2581 2581
2582 // Do tail-call to the runtime system. 2582 // Do tail-call to the runtime system.
2583 Isolate* isolate = masm()->isolate(); 2583 Isolate* isolate = masm()->isolate();
2584 ExternalReference store_ic_property = 2584 ExternalReference store_ic_property =
2585 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate); 2585 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate);
2586 __ TailCallExternalReference(store_ic_property, 4, 1); 2586 __ TailCallExternalReference(store_ic_property, 4, 1);
2587 2587
2588 // Handle store cache miss. 2588 // Handle store cache miss.
2589 __ bind(&miss); 2589 __ bind(&miss);
2590 Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss)); 2590 Handle<Code> ic = isolate->builtins()->StoreIC_Miss();
2591 __ jmp(ic, RelocInfo::CODE_TARGET); 2591 __ jmp(ic, RelocInfo::CODE_TARGET);
2592 2592
2593 // Return the generated code. 2593 // Return the generated code.
2594 return GetCode(INTERCEPTOR, name); 2594 return GetCode(INTERCEPTOR, name);
2595 } 2595 }
2596 2596
2597 2597
2598 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2598 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
2599 JSGlobalPropertyCell* cell, 2599 JSGlobalPropertyCell* cell,
2600 String* name) { 2600 String* name) {
(...skipping 29 matching lines...) Expand all
2630 __ mov(cell_operand, eax); 2630 __ mov(cell_operand, eax);
2631 2631
2632 // Return the value (register eax). 2632 // Return the value (register eax).
2633 Counters* counters = masm()->isolate()->counters(); 2633 Counters* counters = masm()->isolate()->counters();
2634 __ IncrementCounter(counters->named_store_global_inline(), 1); 2634 __ IncrementCounter(counters->named_store_global_inline(), 1);
2635 __ ret(0); 2635 __ ret(0);
2636 2636
2637 // Handle store cache miss. 2637 // Handle store cache miss.
2638 __ bind(&miss); 2638 __ bind(&miss);
2639 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2639 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2640 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2640 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2641 Builtins::StoreIC_Miss));
2642 __ jmp(ic, RelocInfo::CODE_TARGET); 2641 __ jmp(ic, RelocInfo::CODE_TARGET);
2643 2642
2644 // Return the generated code. 2643 // Return the generated code.
2645 return GetCode(NORMAL, name); 2644 return GetCode(NORMAL, name);
2646 } 2645 }
2647 2646
2648 2647
2649 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2648 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
2650 int index, 2649 int index,
2651 Map* transition, 2650 Map* transition,
(...skipping 17 matching lines...) Expand all
2669 GenerateStoreField(masm(), 2668 GenerateStoreField(masm(),
2670 object, 2669 object,
2671 index, 2670 index,
2672 transition, 2671 transition,
2673 edx, ecx, ebx, 2672 edx, ecx, ebx,
2674 &miss); 2673 &miss);
2675 2674
2676 // Handle store cache miss. 2675 // Handle store cache miss.
2677 __ bind(&miss); 2676 __ bind(&miss);
2678 __ DecrementCounter(counters->keyed_store_field(), 1); 2677 __ DecrementCounter(counters->keyed_store_field(), 1);
2679 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2678 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
2680 Builtins::KeyedStoreIC_Miss));
2681 __ jmp(ic, RelocInfo::CODE_TARGET); 2679 __ jmp(ic, RelocInfo::CODE_TARGET);
2682 2680
2683 // Return the generated code. 2681 // Return the generated code.
2684 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2682 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2685 } 2683 }
2686 2684
2687 2685
2688 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2686 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
2689 JSObject* receiver) { 2687 JSObject* receiver) {
2690 // ----------- S t a t e ------------- 2688 // ----------- S t a t e -------------
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2727 // the value in register eax. 2725 // the value in register eax.
2728 __ mov(edx, Operand(eax)); 2726 __ mov(edx, Operand(eax));
2729 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 2727 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2730 __ RecordWrite(edi, 0, edx, ecx); 2728 __ RecordWrite(edi, 0, edx, ecx);
2731 2729
2732 // Done. 2730 // Done.
2733 __ ret(0); 2731 __ ret(0);
2734 2732
2735 // Handle store cache miss. 2733 // Handle store cache miss.
2736 __ bind(&miss); 2734 __ bind(&miss);
2737 Handle<Code> ic( 2735 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
2738 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
2739 __ jmp(ic, RelocInfo::CODE_TARGET); 2736 __ jmp(ic, RelocInfo::CODE_TARGET);
2740 2737
2741 // Return the generated code. 2738 // Return the generated code.
2742 return GetCode(NORMAL, NULL); 2739 return GetCode(NORMAL, NULL);
2743 } 2740 }
2744 2741
2745 2742
2746 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2743 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2747 JSObject* object, 2744 JSObject* object,
2748 JSObject* last) { 2745 JSObject* last) {
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
3277 // depending on the this.x = ...; assignment in the function. 3274 // depending on the this.x = ...; assignment in the function.
3278 SharedFunctionInfo* shared = function->shared(); 3275 SharedFunctionInfo* shared = function->shared();
3279 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3276 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3280 if (shared->IsThisPropertyAssignmentArgument(i)) { 3277 if (shared->IsThisPropertyAssignmentArgument(i)) {
3281 // Check if the argument assigned to the property is actually passed. 3278 // Check if the argument assigned to the property is actually passed.
3282 // If argument is not passed the property is set to undefined, 3279 // If argument is not passed the property is set to undefined,
3283 // otherwise find it on the stack. 3280 // otherwise find it on the stack.
3284 int arg_number = shared->GetThisPropertyAssignmentArgument(i); 3281 int arg_number = shared->GetThisPropertyAssignmentArgument(i);
3285 __ mov(ebx, edi); 3282 __ mov(ebx, edi);
3286 __ cmp(eax, arg_number); 3283 __ cmp(eax, arg_number);
3287 if (Isolate::Current()->cpu_features()->IsSupported(CMOV)) { 3284 if (masm()->isolate()->cpu_features()->IsSupported(CMOV)) {
3288 CpuFeatures::Scope use_cmov(CMOV); 3285 CpuFeatures::Scope use_cmov(CMOV);
3289 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); 3286 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
3290 } else { 3287 } else {
3291 Label not_passed; 3288 Label not_passed;
3292 __ j(below_equal, &not_passed); 3289 __ j(below_equal, &not_passed);
3293 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); 3290 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
3294 __ bind(&not_passed); 3291 __ bind(&not_passed);
3295 } 3292 }
3296 // Store value in the property. 3293 // Store value in the property.
3297 __ mov(Operand(edx, i * kPointerSize), ebx); 3294 __ mov(Operand(edx, i * kPointerSize), ebx);
(...skipping 22 matching lines...) Expand all
3320 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); 3317 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
3321 __ push(ecx); 3318 __ push(ecx);
3322 Counters* counters = masm()->isolate()->counters(); 3319 Counters* counters = masm()->isolate()->counters();
3323 __ IncrementCounter(counters->constructed_objects(), 1); 3320 __ IncrementCounter(counters->constructed_objects(), 1);
3324 __ IncrementCounter(counters->constructed_objects_stub(), 1); 3321 __ IncrementCounter(counters->constructed_objects_stub(), 1);
3325 __ ret(0); 3322 __ ret(0);
3326 3323
3327 // Jump to the generic stub in case the specialized code cannot handle the 3324 // Jump to the generic stub in case the specialized code cannot handle the
3328 // construction. 3325 // construction.
3329 __ bind(&generic_stub_call); 3326 __ bind(&generic_stub_call);
3330 Code* code = Isolate::Current()->builtins()->builtin( 3327 Handle<Code> generic_construct_stub =
3331 Builtins::JSConstructStubGeneric); 3328 masm()->isolate()->builtins()->JSConstructStubGeneric();
3332 Handle<Code> generic_construct_stub(code);
3333 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3329 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3334 3330
3335 // Return the generated code. 3331 // Return the generated code.
3336 return GetCode(); 3332 return GetCode();
3337 } 3333 }
3338 3334
3339 3335
3340 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3336 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3341 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3337 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
3342 // ----------- S t a t e ------------- 3338 // ----------- S t a t e -------------
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
3597 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3593 __ fstp_s(Operand(edi, ebx, times_4, 0));
3598 __ ret(0); 3594 __ ret(0);
3599 } else { 3595 } else {
3600 // Perform float-to-int conversion with truncation (round-to-zero) 3596 // Perform float-to-int conversion with truncation (round-to-zero)
3601 // behavior. 3597 // behavior.
3602 3598
3603 // For the moment we make the slow call to the runtime on 3599 // For the moment we make the slow call to the runtime on
3604 // processors that don't support SSE2. The code in IntegerConvert 3600 // processors that don't support SSE2. The code in IntegerConvert
3605 // (code-stubs-ia32.cc) is roughly what is needed here though the 3601 // (code-stubs-ia32.cc) is roughly what is needed here though the
3606 // conversion failure case does not need to be handled. 3602 // conversion failure case does not need to be handled.
3607 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 3603 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
3608 if (array_type != kExternalIntArray && 3604 if (array_type != kExternalIntArray &&
3609 array_type != kExternalUnsignedIntArray) { 3605 array_type != kExternalUnsignedIntArray) {
3610 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2)); 3606 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2));
3611 CpuFeatures::Scope scope(SSE2); 3607 CpuFeatures::Scope scope(SSE2);
3612 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); 3608 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3613 // ecx: untagged integer value 3609 // ecx: untagged integer value
3614 switch (array_type) { 3610 switch (array_type) {
3615 case kExternalPixelArray: 3611 case kExternalPixelArray:
3616 { // Clamp the value to [0..255]. 3612 { // Clamp the value to [0..255].
3617 NearLabel done; 3613 NearLabel done;
3618 __ test(ecx, Immediate(0xFFFFFF00)); 3614 __ test(ecx, Immediate(0xFFFFFF00));
3619 __ j(zero, &done); 3615 __ j(zero, &done);
3620 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3616 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3621 __ dec_b(ecx); // 0 if negative, 255 if positive. 3617 __ dec_b(ecx); // 0 if negative, 255 if positive.
3622 __ bind(&done); 3618 __ bind(&done);
3623 } 3619 }
3624 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3620 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3625 case kExternalByteArray: 3621 case kExternalByteArray:
3626 case kExternalUnsignedByteArray: 3622 case kExternalUnsignedByteArray:
3627 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3623 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3628 break; 3624 break;
3629 case kExternalShortArray: 3625 case kExternalShortArray:
3630 case kExternalUnsignedShortArray: 3626 case kExternalUnsignedShortArray:
3631 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3627 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3632 break; 3628 break;
3633 default: 3629 default:
3634 UNREACHABLE(); 3630 UNREACHABLE();
3635 break; 3631 break;
3636 } 3632 }
3637 } else { 3633 } else {
3638 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) { 3634 if (masm()->isolate()->cpu_features()->IsSupported(SSE3)) {
3639 CpuFeatures::Scope scope(SSE3); 3635 CpuFeatures::Scope scope(SSE3);
3640 // fisttp stores values as signed integers. To represent the 3636 // fisttp stores values as signed integers. To represent the
3641 // entire range of int and unsigned int arrays, store as a 3637 // entire range of int and unsigned int arrays, store as a
3642 // 64-bit int and discard the high 32 bits. 3638 // 64-bit int and discard the high 32 bits.
3643 // If the value is NaN or +/-infinity, the result is 0x80000000, 3639 // If the value is NaN or +/-infinity, the result is 0x80000000,
3644 // which is automatically zero when taken mod 2^n, n < 32. 3640 // which is automatically zero when taken mod 2^n, n < 32.
3645 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3641 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3646 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3642 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3647 __ fisttp_d(Operand(esp, 0)); 3643 __ fisttp_d(Operand(esp, 0));
3648 __ pop(ecx); 3644 __ pop(ecx);
3649 __ add(Operand(esp), Immediate(kPointerSize)); 3645 __ add(Operand(esp), Immediate(kPointerSize));
3650 } else { 3646 } else {
3651 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2)); 3647 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2));
3652 CpuFeatures::Scope scope(SSE2); 3648 CpuFeatures::Scope scope(SSE2);
3653 // We can easily implement the correct rounding behavior for the 3649 // We can easily implement the correct rounding behavior for the
3654 // range [0, 2^31-1]. For the time being, to keep this code simple, 3650 // range [0, 2^31-1]. For the time being, to keep this code simple,
3655 // make the slow runtime call for values outside this range. 3651 // make the slow runtime call for values outside this range.
3656 // Note: we could do better for signed int arrays. 3652 // Note: we could do better for signed int arrays.
3657 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3653 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3658 // We will need the key if we have to make the slow runtime call. 3654 // We will need the key if we have to make the slow runtime call.
3659 __ push(ecx); 3655 __ push(ecx);
3660 __ LoadPowerOf2(xmm1, ecx, 31); 3656 __ LoadPowerOf2(xmm1, ecx, 31);
3661 __ pop(ecx); 3657 __ pop(ecx);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3694 3690
3695 return GetCode(flags); 3691 return GetCode(flags);
3696 } 3692 }
3697 3693
3698 3694
3699 #undef __ 3695 #undef __
3700 3696
3701 } } // namespace v8::internal 3697 } } // namespace v8::internal
3702 3698
3703 #endif // V8_TARGET_ARCH_IA32 3699 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ia32/virtual-frame-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698