| OLD | NEW |
| 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 1930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1941 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { | 1941 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { |
| 1942 LOperand* value = UseRegister(instr->value()); | 1942 LOperand* value = UseRegister(instr->value()); |
| 1943 // Use a temp to avoid reloading the cell value address in the case where | 1943 // Use a temp to avoid reloading the cell value address in the case where |
| 1944 // we perform a hole check. | 1944 // we perform a hole check. |
| 1945 return instr->RequiresHoleCheck() | 1945 return instr->RequiresHoleCheck() |
| 1946 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) | 1946 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) |
| 1947 : new(zone()) LStoreGlobalCell(value, NULL); | 1947 : new(zone()) LStoreGlobalCell(value, NULL); |
| 1948 } | 1948 } |
| 1949 | 1949 |
| 1950 | 1950 |
| 1951 LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { | |
| 1952 LOperand* context = UseFixed(instr->context(), rsi); | |
| 1953 LOperand* global_object = UseFixed(instr->global_object(), rdx); | |
| 1954 LOperand* value = UseFixed(instr->value(), rax); | |
| 1955 LStoreGlobalGeneric* result = | |
| 1956 new(zone()) LStoreGlobalGeneric(context, global_object, value); | |
| 1957 return MarkAsCall(result, instr); | |
| 1958 } | |
| 1959 | |
| 1960 | |
| 1961 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { | 1951 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 1962 LOperand* context = UseRegisterAtStart(instr->value()); | 1952 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1963 LInstruction* result = | 1953 LInstruction* result = |
| 1964 DefineAsRegister(new(zone()) LLoadContextSlot(context)); | 1954 DefineAsRegister(new(zone()) LLoadContextSlot(context)); |
| 1965 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; | 1955 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; |
| 1966 } | 1956 } |
| 1967 | 1957 |
| 1968 | 1958 |
| 1969 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { | 1959 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { |
| 1970 LOperand* context; | 1960 LOperand* context; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); | 2016 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); |
| 2027 } | 2017 } |
| 2028 | 2018 |
| 2029 | 2019 |
| 2030 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 2020 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2031 ASSERT(instr->key()->representation().IsInteger32()); | 2021 ASSERT(instr->key()->representation().IsInteger32()); |
| 2032 ElementsKind elements_kind = instr->elements_kind(); | 2022 ElementsKind elements_kind = instr->elements_kind(); |
| 2033 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2023 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2034 LLoadKeyed* result = NULL; | 2024 LLoadKeyed* result = NULL; |
| 2035 | 2025 |
| 2036 if (!instr->is_external()) { | 2026 if (!instr->is_typed_elements()) { |
| 2037 LOperand* obj = UseRegisterAtStart(instr->elements()); | 2027 LOperand* obj = UseRegisterAtStart(instr->elements()); |
| 2038 result = new(zone()) LLoadKeyed(obj, key); | 2028 result = new(zone()) LLoadKeyed(obj, key); |
| 2039 } else { | 2029 } else { |
| 2040 ASSERT( | 2030 ASSERT( |
| 2041 (instr->representation().IsInteger32() && | 2031 (instr->representation().IsInteger32() && |
| 2042 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && | 2032 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || |
| 2043 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || | |
| 2044 (instr->representation().IsDouble() && | 2033 (instr->representation().IsDouble() && |
| 2045 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || | 2034 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); |
| 2046 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); | 2035 LOperand* backing_store = UseRegister(instr->elements()); |
| 2047 LOperand* external_pointer = UseRegister(instr->elements()); | 2036 result = new(zone()) LLoadKeyed(backing_store, key); |
| 2048 result = new(zone()) LLoadKeyed(external_pointer, key); | |
| 2049 } | 2037 } |
| 2050 | 2038 |
| 2051 DefineAsRegister(result); | 2039 DefineAsRegister(result); |
| 2052 bool can_deoptimize = instr->RequiresHoleCheck() || | 2040 bool can_deoptimize = instr->RequiresHoleCheck() || |
| 2053 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS); | 2041 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) || |
| 2042 (elements_kind == UINT32_ELEMENTS); |
| 2054 // An unsigned int array load might overflow and cause a deopt, make sure it | 2043 // An unsigned int array load might overflow and cause a deopt, make sure it |
| 2055 // has an environment. | 2044 // has an environment. |
| 2056 return can_deoptimize ? AssignEnvironment(result) : result; | 2045 return can_deoptimize ? AssignEnvironment(result) : result; |
| 2057 } | 2046 } |
| 2058 | 2047 |
| 2059 | 2048 |
| 2060 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 2049 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 2061 LOperand* context = UseFixed(instr->context(), rsi); | 2050 LOperand* context = UseFixed(instr->context(), rsi); |
| 2062 LOperand* object = UseFixed(instr->object(), rdx); | 2051 LOperand* object = UseFixed(instr->object(), rdx); |
| 2063 LOperand* key = UseFixed(instr->key(), rax); | 2052 LOperand* key = UseFixed(instr->key(), rax); |
| 2064 | 2053 |
| 2065 LLoadKeyedGeneric* result = | 2054 LLoadKeyedGeneric* result = |
| 2066 new(zone()) LLoadKeyedGeneric(context, object, key); | 2055 new(zone()) LLoadKeyedGeneric(context, object, key); |
| 2067 return MarkAsCall(DefineFixed(result, rax), instr); | 2056 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2068 } | 2057 } |
| 2069 | 2058 |
| 2070 | 2059 |
| 2071 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2060 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2072 ElementsKind elements_kind = instr->elements_kind(); | 2061 ElementsKind elements_kind = instr->elements_kind(); |
| 2073 | 2062 |
| 2074 if (!instr->is_external()) { | 2063 if (!instr->is_typed_elements()) { |
| 2075 ASSERT(instr->elements()->representation().IsTagged()); | 2064 ASSERT(instr->elements()->representation().IsTagged()); |
| 2076 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2065 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 2077 LOperand* object = NULL; | 2066 LOperand* object = NULL; |
| 2078 LOperand* key = NULL; | 2067 LOperand* key = NULL; |
| 2079 LOperand* val = NULL; | 2068 LOperand* val = NULL; |
| 2080 | 2069 |
| 2081 Representation value_representation = instr->value()->representation(); | 2070 Representation value_representation = instr->value()->representation(); |
| 2082 if (value_representation.IsDouble()) { | 2071 if (value_representation.IsDouble()) { |
| 2083 object = UseRegisterAtStart(instr->elements()); | 2072 object = UseRegisterAtStart(instr->elements()); |
| 2084 val = UseTempRegister(instr->value()); | 2073 val = UseTempRegister(instr->value()); |
| 2085 key = UseRegisterOrConstantAtStart(instr->key()); | 2074 key = UseRegisterOrConstantAtStart(instr->key()); |
| 2086 } else { | 2075 } else { |
| 2087 ASSERT(value_representation.IsSmiOrTagged() || | 2076 ASSERT(value_representation.IsSmiOrTagged() || |
| 2088 value_representation.IsInteger32()); | 2077 value_representation.IsInteger32()); |
| 2089 if (needs_write_barrier) { | 2078 if (needs_write_barrier) { |
| 2090 object = UseTempRegister(instr->elements()); | 2079 object = UseTempRegister(instr->elements()); |
| 2091 val = UseTempRegister(instr->value()); | 2080 val = UseTempRegister(instr->value()); |
| 2092 key = UseTempRegister(instr->key()); | 2081 key = UseTempRegister(instr->key()); |
| 2093 } else { | 2082 } else { |
| 2094 object = UseRegisterAtStart(instr->elements()); | 2083 object = UseRegisterAtStart(instr->elements()); |
| 2095 val = UseRegisterOrConstantAtStart(instr->value()); | 2084 val = UseRegisterOrConstantAtStart(instr->value()); |
| 2096 key = UseRegisterOrConstantAtStart(instr->key()); | 2085 key = UseRegisterOrConstantAtStart(instr->key()); |
| 2097 } | 2086 } |
| 2098 } | 2087 } |
| 2099 | 2088 |
| 2100 return new(zone()) LStoreKeyed(object, key, val); | 2089 return new(zone()) LStoreKeyed(object, key, val); |
| 2101 } | 2090 } |
| 2102 | 2091 |
| 2103 ASSERT( | 2092 ASSERT( |
| 2104 (instr->value()->representation().IsInteger32() && | 2093 (instr->value()->representation().IsInteger32() && |
| 2105 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && | 2094 !IsDoubleOrFloatElementsKind(elements_kind)) || |
| 2106 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || | 2095 (instr->value()->representation().IsDouble() && |
| 2107 (instr->value()->representation().IsDouble() && | 2096 IsDoubleOrFloatElementsKind(elements_kind))); |
| 2108 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || | 2097 ASSERT((instr->is_fixed_typed_array() && |
| 2109 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); | 2098 instr->elements()->representation().IsTagged()) || |
| 2110 ASSERT(instr->elements()->representation().IsExternal()); | 2099 (instr->is_external() && |
| 2100 instr->elements()->representation().IsExternal())); |
| 2111 bool val_is_temp_register = | 2101 bool val_is_temp_register = |
| 2112 elements_kind == EXTERNAL_PIXEL_ELEMENTS || | 2102 elements_kind == EXTERNAL_PIXEL_ELEMENTS || |
| 2113 elements_kind == EXTERNAL_FLOAT_ELEMENTS; | 2103 elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 2104 elements_kind == FLOAT32_ELEMENTS; |
| 2114 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) | 2105 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) |
| 2115 : UseRegister(instr->value()); | 2106 : UseRegister(instr->value()); |
| 2116 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2107 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2117 LOperand* external_pointer = UseRegister(instr->elements()); | 2108 LOperand* backing_store = UseRegister(instr->elements()); |
| 2118 return new(zone()) LStoreKeyed(external_pointer, key, val); | 2109 return new(zone()) LStoreKeyed(backing_store, key, val); |
| 2119 } | 2110 } |
| 2120 | 2111 |
| 2121 | 2112 |
| 2122 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2113 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2123 LOperand* context = UseFixed(instr->context(), rsi); | 2114 LOperand* context = UseFixed(instr->context(), rsi); |
| 2124 LOperand* object = UseFixed(instr->object(), rdx); | 2115 LOperand* object = UseFixed(instr->object(), rdx); |
| 2125 LOperand* key = UseFixed(instr->key(), rcx); | 2116 LOperand* key = UseFixed(instr->key(), rcx); |
| 2126 LOperand* value = UseFixed(instr->value(), rax); | 2117 LOperand* value = UseFixed(instr->value(), rax); |
| 2127 | 2118 |
| 2128 ASSERT(instr->object()->representation().IsTagged()); | 2119 ASSERT(instr->object()->representation().IsTagged()); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2230 LOperand* value = UseFixed(instr->value(), rax); | 2221 LOperand* value = UseFixed(instr->value(), rax); |
| 2231 | 2222 |
| 2232 LStoreNamedGeneric* result = | 2223 LStoreNamedGeneric* result = |
| 2233 new(zone()) LStoreNamedGeneric(context, object, value); | 2224 new(zone()) LStoreNamedGeneric(context, object, value); |
| 2234 return MarkAsCall(result, instr); | 2225 return MarkAsCall(result, instr); |
| 2235 } | 2226 } |
| 2236 | 2227 |
| 2237 | 2228 |
| 2238 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { | 2229 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
| 2239 LOperand* context = UseFixed(instr->context(), rsi); | 2230 LOperand* context = UseFixed(instr->context(), rsi); |
| 2240 LOperand* left = FLAG_new_string_add | 2231 LOperand* left = UseFixed(instr->left(), rdx); |
| 2241 ? UseFixed(instr->left(), rdx) | 2232 LOperand* right = UseFixed(instr->right(), rax); |
| 2242 : UseOrConstantAtStart(instr->left()); | |
| 2243 LOperand* right = FLAG_new_string_add | |
| 2244 ? UseFixed(instr->right(), rax) | |
| 2245 : UseOrConstantAtStart(instr->right()); | |
| 2246 return MarkAsCall( | 2233 return MarkAsCall( |
| 2247 DefineFixed(new(zone()) LStringAdd(context, left, right), rax), instr); | 2234 DefineFixed(new(zone()) LStringAdd(context, left, right), rax), instr); |
| 2248 } | 2235 } |
| 2249 | 2236 |
| 2250 | 2237 |
| 2251 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 2238 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 2252 LOperand* string = UseTempRegister(instr->string()); | 2239 LOperand* string = UseTempRegister(instr->string()); |
| 2253 LOperand* index = UseTempRegister(instr->index()); | 2240 LOperand* index = UseTempRegister(instr->index()); |
| 2254 LOperand* context = UseAny(instr->context()); | 2241 LOperand* context = UseAny(instr->context()); |
| 2255 LStringCharCodeAt* result = | 2242 LStringCharCodeAt* result = |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2502 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2489 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2503 LOperand* object = UseRegister(instr->object()); | 2490 LOperand* object = UseRegister(instr->object()); |
| 2504 LOperand* index = UseTempRegister(instr->index()); | 2491 LOperand* index = UseTempRegister(instr->index()); |
| 2505 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2492 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
| 2506 } | 2493 } |
| 2507 | 2494 |
| 2508 | 2495 |
| 2509 } } // namespace v8::internal | 2496 } } // namespace v8::internal |
| 2510 | 2497 |
| 2511 #endif // V8_TARGET_ARCH_X64 | 2498 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |