| OLD | NEW |
| 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 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2202 // Patch the receiver on the stack with the global proxy if | 2202 // Patch the receiver on the stack with the global proxy if |
| 2203 // necessary. | 2203 // necessary. |
| 2204 if (object->IsGlobalObject()) { | 2204 if (object->IsGlobalObject()) { |
| 2205 ASSERT(depth == kInvalidProtoDepth); | 2205 ASSERT(depth == kInvalidProtoDepth); |
| 2206 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2206 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 2207 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2207 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 2208 } | 2208 } |
| 2209 break; | 2209 break; |
| 2210 | 2210 |
| 2211 case STRING_CHECK: | 2211 case STRING_CHECK: |
| 2212 if (!function->IsBuiltin()) { | 2212 if (!function->IsBuiltin() && !function_info->strict_mode()) { |
| 2213 // Calling non-builtins with a value as receiver requires boxing. | 2213 // Calling non-strict non-builtins with a value as the receiver |
| 2214 // requires boxing. |
| 2214 __ jmp(&miss); | 2215 __ jmp(&miss); |
| 2215 } else { | 2216 } else { |
| 2216 // Check that the object is a string or a symbol. | 2217 // Check that the object is a string or a symbol. |
| 2217 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); | 2218 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); |
| 2218 __ j(above_equal, &miss, not_taken); | 2219 __ j(above_equal, &miss, not_taken); |
| 2219 // Check that the maps starting from the prototype haven't changed. | 2220 // Check that the maps starting from the prototype haven't changed. |
| 2220 GenerateDirectLoadGlobalFunctionPrototype( | 2221 GenerateDirectLoadGlobalFunctionPrototype( |
| 2221 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); | 2222 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); |
| 2222 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 2223 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
| 2223 ebx, edx, edi, name, &miss); | 2224 ebx, edx, edi, name, &miss); |
| 2224 } | 2225 } |
| 2225 break; | 2226 break; |
| 2226 | 2227 |
| 2227 case NUMBER_CHECK: { | 2228 case NUMBER_CHECK: { |
| 2228 if (!function->IsBuiltin()) { | 2229 if (!function->IsBuiltin() && !function_info->strict_mode()) { |
| 2229 // Calling non-builtins with a value as receiver requires boxing. | 2230 // Calling non-strict non-builtins with a value as the receiver |
| 2231 // requires boxing. |
| 2230 __ jmp(&miss); | 2232 __ jmp(&miss); |
| 2231 } else { | 2233 } else { |
| 2232 Label fast; | 2234 Label fast; |
| 2233 // Check that the object is a smi or a heap number. | 2235 // Check that the object is a smi or a heap number. |
| 2234 __ test(edx, Immediate(kSmiTagMask)); | 2236 __ test(edx, Immediate(kSmiTagMask)); |
| 2235 __ j(zero, &fast, taken); | 2237 __ j(zero, &fast, taken); |
| 2236 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); | 2238 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); |
| 2237 __ j(not_equal, &miss, not_taken); | 2239 __ j(not_equal, &miss, not_taken); |
| 2238 __ bind(&fast); | 2240 __ bind(&fast); |
| 2239 // Check that the maps starting from the prototype haven't changed. | 2241 // Check that the maps starting from the prototype haven't changed. |
| 2240 GenerateDirectLoadGlobalFunctionPrototype( | 2242 GenerateDirectLoadGlobalFunctionPrototype( |
| 2241 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); | 2243 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); |
| 2242 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 2244 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
| 2243 ebx, edx, edi, name, &miss); | 2245 ebx, edx, edi, name, &miss); |
| 2244 } | 2246 } |
| 2245 break; | 2247 break; |
| 2246 } | 2248 } |
| 2247 | 2249 |
| 2248 case BOOLEAN_CHECK: { | 2250 case BOOLEAN_CHECK: { |
| 2249 if (!function->IsBuiltin()) { | 2251 if (!function->IsBuiltin() && !function_info->strict_mode()) { |
| 2250 // Calling non-builtins with a value as receiver requires boxing. | 2252 // Calling non-strict non-builtins with a value as the receiver |
| 2253 // requires boxing. |
| 2251 __ jmp(&miss); | 2254 __ jmp(&miss); |
| 2252 } else { | 2255 } else { |
| 2253 Label fast; | 2256 Label fast; |
| 2254 // Check that the object is a boolean. | 2257 // Check that the object is a boolean. |
| 2255 __ cmp(edx, FACTORY->true_value()); | 2258 __ cmp(edx, FACTORY->true_value()); |
| 2256 __ j(equal, &fast, taken); | 2259 __ j(equal, &fast, taken); |
| 2257 __ cmp(edx, FACTORY->false_value()); | 2260 __ cmp(edx, FACTORY->false_value()); |
| 2258 __ j(not_equal, &miss, not_taken); | 2261 __ j(not_equal, &miss, not_taken); |
| 2259 __ bind(&fast); | 2262 __ bind(&fast); |
| 2260 // Check that the maps starting from the prototype haven't changed. | 2263 // Check that the maps starting from the prototype haven't changed. |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2549 } | 2552 } |
| 2550 | 2553 |
| 2551 // Stub never generated for non-global objects that require access | 2554 // Stub never generated for non-global objects that require access |
| 2552 // checks. | 2555 // checks. |
| 2553 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2556 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); |
| 2554 | 2557 |
| 2555 __ pop(ebx); // remove the return address | 2558 __ pop(ebx); // remove the return address |
| 2556 __ push(edx); // receiver | 2559 __ push(edx); // receiver |
| 2557 __ push(ecx); // name | 2560 __ push(ecx); // name |
| 2558 __ push(eax); // value | 2561 __ push(eax); // value |
| 2562 __ push(Immediate(Smi::FromInt(strict_mode_))); |
| 2559 __ push(ebx); // restore return address | 2563 __ push(ebx); // restore return address |
| 2560 | 2564 |
| 2561 // Do tail-call to the runtime system. | 2565 // Do tail-call to the runtime system. |
| 2562 ExternalReference store_ic_property = | 2566 ExternalReference store_ic_property = |
| 2563 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); | 2567 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); |
| 2564 __ TailCallExternalReference(store_ic_property, 3, 1); | 2568 __ TailCallExternalReference(store_ic_property, 4, 1); |
| 2565 | 2569 |
| 2566 // Handle store cache miss. | 2570 // Handle store cache miss. |
| 2567 __ bind(&miss); | 2571 __ bind(&miss); |
| 2568 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2572 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2569 Builtins::StoreIC_Miss)); | 2573 Builtins::StoreIC_Miss)); |
| 2570 __ jmp(ic, RelocInfo::CODE_TARGET); | 2574 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2571 | 2575 |
| 2572 // Return the generated code. | 2576 // Return the generated code. |
| 2573 return GetCode(INTERCEPTOR, name); | 2577 return GetCode(INTERCEPTOR, name); |
| 2574 } | 2578 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2587 | 2591 |
| 2588 // Check that the map of the global has not changed. | 2592 // Check that the map of the global has not changed. |
| 2589 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2593 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
| 2590 Immediate(Handle<Map>(object->map()))); | 2594 Immediate(Handle<Map>(object->map()))); |
| 2591 __ j(not_equal, &miss, not_taken); | 2595 __ j(not_equal, &miss, not_taken); |
| 2592 | 2596 |
| 2593 | 2597 |
| 2594 // Compute the cell operand to use. | 2598 // Compute the cell operand to use. |
| 2595 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell)); | 2599 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell)); |
| 2596 if (Serializer::enabled()) { | 2600 if (Serializer::enabled()) { |
| 2597 __ mov(ecx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 2601 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
| 2598 cell_operand = FieldOperand(ecx, JSGlobalPropertyCell::kValueOffset); | 2602 cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); |
| 2599 } | 2603 } |
| 2600 | 2604 |
| 2601 // Check that the value in the cell is not the hole. If it is, this | 2605 // Check that the value in the cell is not the hole. If it is, this |
| 2602 // cell could have been deleted and reintroducing the global needs | 2606 // cell could have been deleted and reintroducing the global needs |
| 2603 // to update the property details in the property dictionary of the | 2607 // to update the property details in the property dictionary of the |
| 2604 // global object. We bail out to the runtime system to do that. | 2608 // global object. We bail out to the runtime system to do that. |
| 2605 __ cmp(cell_operand, FACTORY->the_hole_value()); | 2609 __ cmp(cell_operand, FACTORY->the_hole_value()); |
| 2606 __ j(equal, &miss); | 2610 __ j(equal, &miss); |
| 2607 | 2611 |
| 2608 // Store the value in the cell. | 2612 // Store the value in the cell. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2713 __ bind(&miss); | 2717 __ bind(&miss); |
| 2714 Handle<Code> ic( | 2718 Handle<Code> ic( |
| 2715 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss)); | 2719 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss)); |
| 2716 __ jmp(ic, RelocInfo::CODE_TARGET); | 2720 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2717 | 2721 |
| 2718 // Return the generated code. | 2722 // Return the generated code. |
| 2719 return GetCode(NORMAL, NULL); | 2723 return GetCode(NORMAL, NULL); |
| 2720 } | 2724 } |
| 2721 | 2725 |
| 2722 | 2726 |
| 2727 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray( |
| 2728 JSObject* receiver) { |
| 2729 // ----------- S t a t e ------------- |
| 2730 // -- eax : value |
| 2731 // -- ecx : key |
| 2732 // -- edx : receiver |
| 2733 // -- esp[0] : return address |
| 2734 // ----------------------------------- |
| 2735 Label miss; |
| 2736 |
| 2737 // Check that the map matches. |
| 2738 __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false); |
| 2739 |
| 2740 // Do the load. |
| 2741 GenerateFastPixelArrayStore(masm(), |
| 2742 edx, |
| 2743 ecx, |
| 2744 eax, |
| 2745 edi, |
| 2746 ebx, |
| 2747 true, |
| 2748 &miss, |
| 2749 &miss, |
| 2750 NULL, |
| 2751 &miss); |
| 2752 |
| 2753 // Handle store cache miss. |
| 2754 __ bind(&miss); |
| 2755 Handle<Code> ic(Isolate::Current()->builtins()->builtin( |
| 2756 Builtins::KeyedStoreIC_Miss)); |
| 2757 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 2758 |
| 2759 // Return the generated code. |
| 2760 return GetCode(NORMAL, NULL); |
| 2761 } |
| 2762 |
| 2763 |
| 2723 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2764 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
| 2724 JSObject* object, | 2765 JSObject* object, |
| 2725 JSObject* last) { | 2766 JSObject* last) { |
| 2726 // ----------- S t a t e ------------- | 2767 // ----------- S t a t e ------------- |
| 2727 // -- eax : receiver | 2768 // -- eax : receiver |
| 2728 // -- ecx : name | 2769 // -- ecx : name |
| 2729 // -- esp[0] : return address | 2770 // -- esp[0] : return address |
| 2730 // ----------------------------------- | 2771 // ----------------------------------- |
| 2731 Label miss; | 2772 Label miss; |
| 2732 | 2773 |
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3679 // -- eax : value | 3720 // -- eax : value |
| 3680 // -- ecx : key | 3721 // -- ecx : key |
| 3681 // -- edx : receiver | 3722 // -- edx : receiver |
| 3682 // -- esp[0] : return address | 3723 // -- esp[0] : return address |
| 3683 // ----------------------------------- | 3724 // ----------------------------------- |
| 3684 | 3725 |
| 3685 __ pop(ebx); | 3726 __ pop(ebx); |
| 3686 __ push(edx); | 3727 __ push(edx); |
| 3687 __ push(ecx); | 3728 __ push(ecx); |
| 3688 __ push(eax); | 3729 __ push(eax); |
| 3689 __ push(ebx); | 3730 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes |
| 3731 __ push(Immediate(Smi::FromInt( |
| 3732 Code::ExtractExtraICStateFromFlags(flags) & kStrictMode))); |
| 3733 __ push(ebx); // return address |
| 3690 | 3734 |
| 3691 // Do tail-call to runtime routine. | 3735 // Do tail-call to runtime routine. |
| 3692 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); | 3736 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
| 3693 | 3737 |
| 3694 return GetCode(flags); | 3738 return GetCode(flags); |
| 3695 } | 3739 } |
| 3696 | 3740 |
| 3697 | 3741 |
| 3698 #undef __ | 3742 #undef __ |
| 3699 | 3743 |
| 3700 } } // namespace v8::internal | 3744 } } // namespace v8::internal |
| 3701 | 3745 |
| 3702 #endif // V8_TARGET_ARCH_IA32 | 3746 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |